rustwav_core/
lib.rs

1mod wavcore;
2mod wavreader;
3mod wavwriter;
4mod adpcm;
5
6#[macro_use]
7mod hacks;
8
9/// * The encoders for the `WaveWriter`, each of these provides the same API for it to use. You can use it too.
10pub mod encoders;
11
12/// * The decoders for the `WaveReader`, each of these provides the same API for it to use. You can use it too.
13pub mod decoders;
14
15/// * The resampler
16#[doc(inline)]
17pub use resampler;
18
19#[doc(hidden)]
20pub use sampletypes::{i24, u24};
21
22pub use sampletypes::{SampleFrom, SampleType};
23pub use wavreader::{WaveDataSource, WaveReader};
24pub use wavwriter::WaveWriter;
25
26/// * Errors returned from most of the function in this library.
27pub mod errors;
28
29/// * Utilities for IO
30pub use io_utils;
31
32/// * The utility for both you and me to convert waveform format and do resampling and convert sample types.
33pub use audioutils;
34
35/// * The downmixer
36pub use downmixer;
37
38/// * Misc utilities
39pub mod utils {
40    /// * Copiable buffer, a tinier `Vec`, uses a fixed-size array to store a variable number of items.
41    pub use copiablebuf::CopiableBuffer;
42
43    /// * File hasher to calculate the hash for a section of a file, the hash is `u64` size. The `Write` trait was implemented for it.
44    pub use filehasher::FileHasher;
45
46    // * A string encode/decode library that sometimes do things savagely
47    pub use savagestr::{SavageStringCodecs, StringCodecMaps};
48
49    /// * A function to gather all of the needed chunks from a `WaveReader` and constructs the `cue` data full of the info.
50    /// * WAV files seldom contain the `cue` data, normally the cue data is separated into a `.cue` file.
51    pub use crate::wavcore::create_full_info_cue_data;
52}
53
54/// * Iterators for `WaveReader` to decode audio samples.
55pub mod iterators {
56    pub use crate::wavreader::{FrameIntoIter, FrameIter, MonoIntoIter, MonoIter, StereoIntoIter, StereoIter};
57}
58
59/// * WAV file format specs
60pub mod format_specs {
61    pub use crate::wavcore::{DataFormat, SampleFormat, Spec, WaveSampleType};
62
63    /// * All of the supported WAV format tags
64    pub mod format_tags {
65        pub use crate::wavcore::format_tags::*;
66    }
67
68    /// * All of the supported WAV format GUIDs from the extensible data from the `fmt ` chunk.
69    pub mod guids {
70        pub use crate::wavcore::guids::*;
71    }
72}
73
74/// * Encoder creation options
75pub mod options {
76    pub use crate::wavwriter::FileSizeOption;
77
78    #[doc(inline)]
79    pub use crate::wavcore::AdpcmSubFormat;
80
81    #[doc(inline)]
82    pub use crate::wavcore::flac::{FlacCompression, FlacEncoderParams};
83
84    #[doc(inline)]
85    pub use crate::wavcore::mp3::{Mp3Bitrate, Mp3Channels, Mp3EncoderOptions, Mp3Quality, Mp3VbrMode};
86
87    #[doc(inline)]
88    pub use crate::wavcore::opus::{OpusBitrate, OpusEncoderOptions, OpusEncoderSampleDuration};
89
90    #[doc(inline)]
91    pub use crate::wavcore::oggvorbis::{OggVorbisEncoderParams, OggVorbisMode, OggVorbisBitrateStrategy};
92}
93
94/// * WAV chunks
95pub mod chunks {
96    pub use crate::wavcore::{
97        FmtChunk,
98        SlntChunk,
99        BextChunk,
100        InstChunk,
101        AcidChunk,
102        TrknChunk,
103        CueChunk,
104        PlstChunk,
105        SmplChunk,
106        ListChunk,
107        Id3,
108        JunkChunk,
109        FullInfoCuePoint,
110        ListInfo,
111        AdtlChunk,
112        LablChunk,
113        NoteChunk,
114        LtxtChunk,
115        FileChunk,
116    };
117
118    /// * WAV `fmt ` chunk extension data
119    pub mod ext {
120        pub use crate::wavcore::{
121            FmtExtension,
122            ExtensionData,
123            AdpcmMsData,
124            AdpcmImaData,
125            Mp3Data,
126            OggVorbisData,
127            OggVorbisWithHeaderData,
128            ExtensibleData,
129        };
130    }
131}
132
133use resampler::Resampler;
134
135/// * Transfer audio from the decoder to the encoder with resampling.
136/// * This allows to transfer of audio from the decoder to a different sample rate encoder.
137pub fn transfer_audio_from_decoder_to_encoder(decoder: &mut WaveReader, encoder: &mut WaveWriter) {
138    // The decoding audio spec
139    let decode_spec = decoder.spec();
140
141    // The encoding audio spec
142    let encode_spec = encoder.spec();
143
144    let decode_channels = decode_spec.channels;
145    let encode_channels = encode_spec.channels;
146    let decode_sample_rate = decode_spec.sample_rate;
147    let encode_sample_rate = encode_spec.sample_rate;
148
149    // Get the best FFT size for the resampler.
150    let fft_size = Resampler::get_rounded_up_fft_size(std::cmp::max(encode_sample_rate, decode_sample_rate));
151
152    // This is the resampler, if the decoder's sample rate is different than the encode sample rate, use the resampler to help stretch or compress the waveform.
153    // Otherwise, it's not needed there.
154    let resampler = Resampler::new(fft_size);
155
156    // The number of channels must match
157    assert_eq!(encode_channels, decode_channels);
158
159    // Process size is for the resampler to process the waveform, it is the length of the source waveform slice.
160    let process_size = resampler.get_process_size(fft_size, decode_sample_rate, encode_sample_rate);
161
162    // There are three types of iterators for three types of audio channels: mono, stereo, and more than 2 channels of audio.
163    // Usually, the third iterator can handle all numbers of channels, but it's the slowest iterator.
164    match encode_channels {
165        1 => {
166            let mut iter = decoder.mono_iter::<f32>().unwrap();
167            loop {
168                let block: Vec<f32> = iter.by_ref().take(process_size).collect();
169                if block.is_empty() {
170                    break;
171                }
172                let block = audioutils::do_resample_mono(
173                    &resampler,
174                    &block,
175                    decode_sample_rate,
176                    encode_sample_rate,
177                );
178                encoder.write_mono_channel(&block).unwrap();
179            }
180        }
181        2 => {
182            let mut iter = decoder.stereo_iter::<f32>().unwrap();
183            loop {
184                let block: Vec<(f32, f32)> = iter.by_ref().take(process_size).collect();
185                if block.is_empty() {
186                    break;
187                }
188                let block = audioutils::do_resample_stereo(
189                    &resampler,
190                    &block,
191                    decode_sample_rate,
192                    encode_sample_rate,
193                );
194                encoder.write_stereos(&block).unwrap();
195            }
196        }
197        _ => {
198            let mut iter = decoder.frame_iter::<f32>().unwrap();
199            loop {
200                let block: Vec<Vec<f32>> = iter.by_ref().take(process_size).collect();
201                if block.is_empty() {
202                    break;
203                }
204                let block = audioutils::do_resample_frames(
205                    &resampler,
206                    &block,
207                    decode_sample_rate,
208                    encode_sample_rate,
209                );
210                encoder.write_frames(&block).unwrap();
211            }
212        }
213    }
214}