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