@@ -5,29 +5,13 @@ use std::io::{BufReader, BufWriter, Read, Seek, SeekFrom, Write, Cursor};
55use std:: path:: { Path , PathBuf } ;
66use rubato:: { Resampler , SincFixedIn , SincInterpolationType , SincInterpolationParameters , WindowFunction } ;
77
8- use crate :: wav:: parse_smpl_chunk;
8+ use crate :: wav:: { parse_smpl_chunk, WavFmt , OtherChunk } ;
99
1010const TARGET_SAMPLE_RATE : u32 = 48000 ;
1111const I16_MAX_F : f32 = 32768.0 ; // 2^15
1212const I24_MAX_F : f32 = 8388608.0 ; // 2^23
1313const I32_MAX_F : f32 = 2147483648.0 ; // 2^31
1414
15- /// A simple struct to hold the format info we care about.
16- #[ derive( Debug , Clone , Copy ) ]
17- pub struct WavFormat {
18- pub audio_format : u16 ,
19- pub channel_count : u16 ,
20- pub sampling_rate : u32 ,
21- pub bits_per_sample : u16 ,
22- }
23-
24- /// A struct to hold metadata chunks (like 'smpl') that we want to preserve.
25- #[ derive( Debug , Clone ) ]
26- pub struct OtherChunk {
27- pub id : [ u8 ; 4 ] ,
28- pub data : Vec < u8 > ,
29- }
30-
3115#[ derive( Debug ) ]
3216pub struct SampleMetadata {
3317 pub loop_info : Option < ( u32 , u32 ) > ,
@@ -47,12 +31,12 @@ fn read_i24<R: Read>(reader: &mut R) -> std::io::Result<i32> {
4731/// Helper to read all audio data from a reader into f32 waves
4832fn read_f32_waves < R : Read > (
4933 mut reader : R ,
50- format : WavFormat ,
34+ format : WavFmt ,
5135 data_size : u32
5236) -> Result < Vec < Vec < f32 > > > {
5337 let bytes_per_sample = ( format. bits_per_sample / 8 ) as u32 ;
54- let num_frames = data_size / ( bytes_per_sample * format. channel_count as u32 ) ;
55- let num_channels = format. channel_count as usize ;
38+ let num_frames = data_size / ( bytes_per_sample * format. num_channels as u32 ) ;
39+ let num_channels = format. num_channels as usize ;
5640 let mut output_waves = vec ! [ Vec :: with_capacity( num_frames as usize ) ; num_channels] ;
5741
5842 for _ in 0 ..num_frames {
@@ -117,7 +101,7 @@ fn write_f32_waves_to_bytes(
117101pub fn parse_wav_metadata < R : Read + Seek > (
118102 reader : & mut R ,
119103 full_path_for_logs : & Path ,
120- ) -> Result < ( WavFormat , Vec < OtherChunk > , u64 , u32 ) > {
104+ ) -> Result < ( WavFmt , Vec < OtherChunk > , u64 , u32 ) > {
121105 let mut riff_header = [ 0 ; 4 ] ;
122106 reader. read_exact ( & mut riff_header) ?;
123107 if & riff_header != b"RIFF" { return Err ( anyhow ! ( "Not a RIFF file: {:?}" , full_path_for_logs) ) ; }
@@ -126,7 +110,7 @@ pub fn parse_wav_metadata<R: Read + Seek>(
126110 reader. read_exact ( & mut wave_header) ?;
127111 if & wave_header != b"WAVE" { return Err ( anyhow ! ( "Not a WAVE file: {:?}" , full_path_for_logs) ) ; }
128112
129- let mut format_chunk: Option < WavFormat > = None ;
113+ let mut format_chunk: Option < WavFmt > = None ;
130114 let mut data_chunk_info: Option < ( u64 , u32 ) > = None ; // (offset, size)
131115 let mut other_chunks: Vec < OtherChunk > = Vec :: new ( ) ;
132116
@@ -141,10 +125,10 @@ pub fn parse_wav_metadata<R: Read + Seek>(
141125 let mut fmt_data = vec ! [ 0 ; chunk_size as usize ] ;
142126 reader. read_exact ( & mut fmt_data) ?;
143127 let mut cursor = Cursor :: new ( fmt_data) ;
144- format_chunk = Some ( WavFormat {
128+ format_chunk = Some ( WavFmt {
145129 audio_format : cursor. read_u16 :: < LittleEndian > ( ) ?,
146- channel_count : cursor. read_u16 :: < LittleEndian > ( ) ?,
147- sampling_rate : cursor. read_u32 :: < LittleEndian > ( ) ?,
130+ num_channels : cursor. read_u16 :: < LittleEndian > ( ) ?,
131+ sample_rate : cursor. read_u32 :: < LittleEndian > ( ) ?,
148132 bits_per_sample : {
149133 cursor. seek ( SeekFrom :: Start ( 14 ) ) ?;
150134 cursor. read_u16 :: < LittleEndian > ( ) ?
@@ -181,10 +165,10 @@ pub fn load_sample_as_f32(path: &Path) -> Result<(Vec<f32>, SampleMetadata)> {
181165 parse_wav_metadata ( & mut reader, path) ?;
182166
183167 // Sanity check
184- if format. sampling_rate != TARGET_SAMPLE_RATE {
168+ if format. sample_rate != TARGET_SAMPLE_RATE {
185169 return Err ( anyhow ! (
186170 "Attempted to cache non-processed file: {:?} (Rate: {}Hz)" ,
187- path, format. sampling_rate
171+ path, format. sample_rate
188172 ) ) ;
189173 }
190174
@@ -199,7 +183,7 @@ pub fn load_sample_as_f32(path: &Path) -> Result<(Vec<f32>, SampleMetadata)> {
199183
200184 let metadata = SampleMetadata {
201185 loop_info,
202- channel_count : format. channel_count ,
186+ channel_count : format. num_channels ,
203187 } ;
204188
205189 reader. seek ( SeekFrom :: Start ( data_offset) ) ?;
@@ -248,7 +232,7 @@ pub fn process_sample_file(
248232 let target_sample_rate = TARGET_SAMPLE_RATE ;
249233 let target_is_float = format. audio_format == 3 && !convert_to_16_bit;
250234
251- let needs_resample = format. sampling_rate != target_sample_rate || pitch_tuning_cents != 0.0 ;
235+ let needs_resample = format. sample_rate != target_sample_rate || pitch_tuning_cents != 0.0 ;
252236 let needs_bit_change = target_bits != format. bits_per_sample || ( format. audio_format == 3 && !target_is_float) ;
253237
254238 // Early exit
@@ -267,7 +251,7 @@ pub fn process_sample_file(
267251 if pitch_tuning_cents != 0.0 {
268252 suffixes. push ( format ! ( "p{:+.1}" , pitch_tuning_cents) ) ;
269253 }
270- if format. sampling_rate != target_sample_rate {
254+ if format. sample_rate != target_sample_rate {
271255 suffixes. push ( format ! ( "{}k" , target_sample_rate / 1000 ) ) ;
272256 }
273257
@@ -294,7 +278,7 @@ pub fn process_sample_file(
294278 // Resample if needed
295279 let output_waves = if needs_resample {
296280 let pitch_factor = 2.0f64 . powf ( pitch_tuning_cents as f64 / 1200.0 ) ;
297- let effective_input_rate = format. sampling_rate as f64 / pitch_factor;
281+ let effective_input_rate = format. sample_rate as f64 / pitch_factor;
298282 let resample_ratio = target_sample_rate as f64 / effective_input_rate;
299283
300284 // Use high-quality Sinc resampler for offline processing
@@ -328,7 +312,7 @@ pub fn process_sample_file(
328312 let new_data_size = final_data_chunk. len ( ) as u32 ;
329313 let new_bits_per_sample: u16 = target_bits;
330314 let new_audio_format = if target_is_float { 3 } else { 1 } ;
331- let new_block_align = format. channel_count * ( new_bits_per_sample / 8 ) ;
315+ let new_block_align = format. num_channels * ( new_bits_per_sample / 8 ) ;
332316 let new_byte_rate = target_sample_rate * new_block_align as u32 ; // Use target rate
333317
334318 let mut other_chunks_total_size: u32 = 0 ;
@@ -348,7 +332,7 @@ pub fn process_sample_file(
348332 writer. write_all ( b"fmt " ) ?;
349333 writer. write_u32 :: < LittleEndian > ( 16 ) ?; // chunk size (minimal PCM)
350334 writer. write_u16 :: < LittleEndian > ( new_audio_format) ?;
351- writer. write_u16 :: < LittleEndian > ( format. channel_count ) ?;
335+ writer. write_u16 :: < LittleEndian > ( format. num_channels ) ?;
352336 writer. write_u32 :: < LittleEndian > ( target_sample_rate) ?; // <-- Write new rate
353337 writer. write_u32 :: < LittleEndian > ( new_byte_rate) ?;
354338 writer. write_u16 :: < LittleEndian > ( new_block_align) ?;
0 commit comments