1mod errors;
2mod savagestr;
3mod readwrite;
4mod copiablebuf;
5mod filehasher;
6mod adpcm;
7mod xlaw;
8mod wavcore;
9mod wavreader;
10mod wavwriter;
11mod hacks;
12
13pub mod utils;
15
16pub mod encoders;
18
19pub mod decoders;
21
22#[doc(hidden)]
23pub use sampletypes::{i24, u24};
24
25pub use sampletypes::{SampleType, SampleFrom};
26pub use readwrite::{Reader, Writer, ReadBridge, WriteBridge, SharedReader, SharedWriter, string_io};
27pub use wavcore::{Spec, SampleFormat, DataFormat};
28pub use wavreader::{WaveDataSource, WaveReader, FrameIter, StereoIter, MonoIter, FrameIntoIter, StereoIntoIter, MonoIntoIter};
29pub use wavwriter::{FileSizeOption, WaveWriter};
30pub use resampler::Resampler;
31pub use errors::{AudioReadError, AudioError, AudioWriteError};
32pub use wavcore::{AdpcmSubFormat};
33pub use wavcore::{FlacEncoderParams, FlacCompression};
34
35#[doc(inline)]
36pub use encoders::{Mp3EncoderOptions, Mp3Channels, Mp3Quality, Mp3Bitrate, Mp3VbrMode};
37
38#[doc(inline)]
39pub use encoders::{OpusEncoderOptions, OpusBitrate, OpusEncoderSampleDuration};
40
41#[doc(inline)]
42pub use encoders::{VorbisEncoderParams, VorbisBitrateStrategy};
43
44pub const FORMATS: [(&str, DataFormat); 10] = [
46 ("pcm", DataFormat::Pcm),
47 ("pcm-alaw", DataFormat::PcmALaw),
48 ("pcm-ulaw", DataFormat::PcmMuLaw),
49 ("adpcm-ms", DataFormat::Adpcm(AdpcmSubFormat::Ms)),
50 ("adpcm-ima", DataFormat::Adpcm(AdpcmSubFormat::Ima)),
51 ("adpcm-yamaha", DataFormat::Adpcm(AdpcmSubFormat::Yamaha)),
52 ("mp3", DataFormat::Mp3(Mp3EncoderOptions{
53 channels: Mp3Channels::NotSet,
54 quality: Mp3Quality::Best,
55 bitrate: Mp3Bitrate::Kbps320,
56 vbr_mode: Mp3VbrMode::Off,
57 id3tag: None,
58 })),
59 ("opus", DataFormat::Opus(OpusEncoderOptions{
60 bitrate: OpusBitrate::Max,
61 encode_vbr: false,
62 samples_cache_duration: OpusEncoderSampleDuration::MilliSec60,
63 })),
64 ("flac", DataFormat::Flac(FlacEncoderParams{
65 verify_decoded: false,
66 compression: FlacCompression::Level8,
67 channels: 2,
68 sample_rate: 44100,
69 bits_per_sample: 32,
70 total_samples_estimate: 0,
71 })),
72 ("vorbis", DataFormat::Vorbis(VorbisEncoderParams{
73 channels: 2,
74 sample_rate: 44100,
75 stream_serial: None,
76 bitrate: None,
77 minimum_page_data_size: None,
78 }))
79];
80
81pub fn transfer_audio_from_decoder_to_encoder(decoder: &mut WaveReader, encoder: &mut WaveWriter) {
84 const FFT_SIZE: usize = 65536;
88
89 let resampler = Resampler::new(FFT_SIZE);
92
93 let decode_spec = decoder.spec();
95
96 let encode_spec = encoder.spec();
98
99 let decode_channels = decode_spec.channels;
100 let encode_channels = encode_spec.channels;
101 let decode_sample_rate = decode_spec.sample_rate;
102 let encode_sample_rate = encode_spec.sample_rate;
103
104 assert_eq!(encode_channels, decode_channels);
106
107 let process_size = resampler.get_process_size(FFT_SIZE, decode_sample_rate, encode_sample_rate);
109
110 match encode_channels {
113 1 => {
114 let mut iter = decoder.mono_iter::<f32>().unwrap();
115 loop {
116 let block: Vec<f32> = iter.by_ref().take(process_size).collect();
117 if block.is_empty() {
118 break;
119 }
120 let block = utils::do_resample_mono(&resampler, &block, decode_sample_rate, encode_sample_rate);
121 encoder.write_mono_channel(&block).unwrap();
122 }
123 },
124 2 => {
125 let mut iter = decoder.stereo_iter::<f32>().unwrap();
126 loop {
127 let block: Vec<(f32, f32)> = iter.by_ref().take(process_size).collect();
128 if block.is_empty() {
129 break;
130 }
131 let block = utils::do_resample_stereo(&resampler, &block, decode_sample_rate, encode_sample_rate);
132 encoder.write_stereos(&block).unwrap();
133 }
134 },
135 _ => {
136 let mut iter = decoder.frame_iter::<f32>().unwrap();
137 loop {
138 let block: Vec<Vec<f32>> = iter.by_ref().take(process_size).collect();
139 if block.is_empty() {
140 break;
141 }
142 let block = utils::do_resample_frames(&resampler, &block, decode_sample_rate, encode_sample_rate);
143 encoder.write_frames(&block).unwrap();
144 }
145 }
146 }
147}
148
149use std::{env::args, process::ExitCode, error::Error};
150
151pub fn test(arg1: &str, arg2: &str, arg3: &str, arg4: &str) -> Result<(), Box<dyn Error>> {
157 let mut data_format = DataFormat::Unspecified;
158 for format in FORMATS {
159 if arg1 == format.0 {
160 data_format = format.1;
161 break;
162 }
163 }
164
165 if data_format == DataFormat::Unspecified {
167 return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, format!("Unknown format `{arg1}`. Please input one of these:\n{}", FORMATS.iter().map(|(s, _v)|{s.to_string()}).collect::<Vec<String>>().join(", "))).into());
168 }
169
170 println!("======== TEST 1 ========");
171 println!("{:?}", data_format);
172
173 let mut wavereader = WaveReader::open(arg2).unwrap();
175
176 let orig_spec = wavereader.spec();
177
178 let mut spec = Spec {
180 channels: orig_spec.channels,
181 channel_mask: 0,
182 sample_rate: orig_spec.sample_rate,
183 bits_per_sample: 16,
184 sample_format: SampleFormat::Int,
185 };
186
187 match data_format {
188 DataFormat::Mp3(ref mut options) => {
189 match spec.channels {
190 1 => options.channels = Mp3Channels::Mono,
191 2 => options.channels = Mp3Channels::JointStereo,
192 o => panic!("MP3 format can't encode {o} channels audio."),
193 }
194 },
195 DataFormat::Opus(ref options) => {
196 spec.sample_rate = options.get_rounded_up_sample_rate(spec.sample_rate);
197 },
198 DataFormat::Flac(ref mut options) => {
199 options.channels = spec.channels;
200 options.sample_rate = spec.sample_rate;
201 options.bits_per_sample = spec.bits_per_sample as u32;
202 },
203 _ => (),
204 }
205
206 #[allow(unused_imports)]
208 use FileSizeOption::{NeverLargerThan4GB, AllowLargerThan4GB, ForceUse4GBFormat};
209
210 let mut wavewriter = WaveWriter::create(arg3, &spec, data_format, NeverLargerThan4GB).unwrap();
212
213 transfer_audio_from_decoder_to_encoder(&mut wavereader, &mut wavewriter);
215
216 wavewriter.inherit_metadata_from_reader(&wavereader, true);
218
219 dbg!(&wavereader);
221 dbg!(&wavewriter);
222
223 drop(wavereader);
224 drop(wavewriter);
225
226 println!("======== TEST 2 ========");
227
228 let spec2 = Spec {
229 channels: spec.channels,
230 channel_mask: 0,
231 sample_rate: orig_spec.sample_rate,
232 bits_per_sample: 16,
233 sample_format: SampleFormat::Int,
234 };
235
236 let mut wavereader_2 = WaveReader::open(arg3).unwrap();
237 let mut wavewriter_2 = WaveWriter::create(arg4, &spec2, DataFormat::Pcm, NeverLargerThan4GB).unwrap();
238
239 transfer_audio_from_decoder_to_encoder(&mut wavereader_2, &mut wavewriter_2);
241
242 wavewriter_2.inherit_metadata_from_reader(&wavereader_2, true);
244
245
246 dbg!(&wavereader_2);
248 dbg!(&wavewriter_2);
249
250 drop(wavereader_2);
251 drop(wavewriter_2);
252
253 Ok(())
254}
255
256#[allow(dead_code)]
262pub fn test_wav() -> ExitCode {
263 let args: Vec<String> = args().collect();
264 if args.len() < 5 {return ExitCode::from(1);}
265 let input_wav = &args[1];
266 let output_wav = &args[2];
267 let reinput_wav = &args[3];
268 let reoutput_wav = &args[4];
269 match test(input_wav, output_wav, reinput_wav, reoutput_wav) {
270 Ok(_) => ExitCode::from(0),
271 Err(e) => {
272 eprintln!("{:?}", e);
273 ExitCode::from(2)
274 },
275 }
276}
277
278macro_rules! test_fn {
279 ($name:ident, $index:expr) => {
280 #[test]
281 pub fn $name() {
282 let fmt = FORMATS[$index].0;
283 test(fmt, "test.wav", &format!("{fmt}_test_encode.wav"), &format!("{fmt}_test_decode.wav")).unwrap();
284 }
285 }
286}
287
288test_fn!(test0, 0);
289test_fn!(test1, 1);
290test_fn!(test2, 2);
291test_fn!(test3, 3);
292test_fn!(test4, 4);
293test_fn!(test5, 5);
294test_fn!(test6, 6);
295test_fn!(test7, 7);
296test_fn!(test8, 8);
297test_fn!(test9, 9);