2 releases
0.1.2 | Sep 24, 2024 |
---|---|
0.1.1 | Sep 23, 2024 |
0.1.0 |
|
#414 in Asynchronous
26 downloads per month
230KB
595 lines
stream-wave-parser
The stream-wave-parser
is a crate that treats a stream from WAVE file.
You can create a WaveStream
from impl Stream<Item = Result<Vec<u8>>>
that is WAVE
data.
(e.g. An input stream data is typically from reqwest::Response::bytes_stream()
.)
The WaveStream
provides a spec()
method that returns WAVE metadata (sample_rate
, bits_per_sample
, etc.).
And the WaveStream
also provides into_data()
that is the stream of the data in data
chunk.
Mixer
You can create a WaveChannelMixer
that converts multiple channels data into a single channel data.
Usages
use stream_wave_parser::WaveStream;
use futures_util::StreamExt as _;
use futures_util::stream::iter;
#[tokio::main]
async fn main() {
// create wave stream.
let chunks = create_sine_wave()
.chunks(256)
.map(|x| Ok(x.iter().cloned().collect::<Vec<_>>()))
.collect::<Vec<_>>();
let stream = iter(chunks);
// read stream by `WaveStream`.
let mut stream = WaveStream::new(stream);
let spec = stream.spec().await.unwrap();
assert_eq!(spec.pcm_format, 1);
assert_eq!(spec.channels, 1);
assert_eq!(spec.sample_rate, 8000);
assert_eq!(spec.bits_per_sample, 16);
let data_size = 16000; // 8000 samples x 2 Bytes (16 bits per sample)
let mut data = stream.into_data().await;
let mut size = 0;
while let Some(chunk) = data.next().await {
let chunk = chunk.unwrap();
size += chunk.len();
}
assert_eq!(data_size, size as u32);
}
/// create sine wave (440 Hz 1 seconds)
fn create_sine_wave() -> Vec<u8> {
use std::f32::consts::PI;
let data_chunk = (0..)
.enumerate()
.map(|(_, idx)| {
let t = idx as f32 / 8000.0;
let sample = (t * 440. * 2. * PI).sin();
((sample * i16::MAX as f32) as i16).to_le_bytes()
})
.take(8000)
.flatten()
.collect::<Vec<u8>>();
let mut wave = vec![];
let riff_length = ((data_chunk.len() + 36) as u32).to_le_bytes();
wave.extend(b"RIFF");
wave.extend(riff_length);
wave.extend(b"WAVE");
wave.extend(b"fmt ");
wave.extend(16u32.to_le_bytes()); // `fmt ` chunk size
wave.extend(1u16.to_le_bytes()); // PCM format
wave.extend(1u16.to_le_bytes()); // channels
wave.extend(8000u32.to_le_bytes()); // sample rate
wave.extend(16000u32.to_le_bytes()); // bit rate
wave.extend(2u16.to_le_bytes()); // block size
wave.extend(16u16.to_le_bytes()); // bits per sample
wave.extend(b"data");
wave.extend((data_chunk.len() as u32).to_le_bytes());
wave.extend(data_chunk);
wave
}
Dependencies
~530–710KB
~14K SLoC