Iterate over samples
This commit is contained in:
parent
c4edb01e68
commit
70556488fc
|
@ -9,6 +9,7 @@ panic = "abort"
|
|||
[dependencies]
|
||||
clap = {version = "4.4.11", features = ["derive"]}
|
||||
image = "0.24.7"
|
||||
hound = "3.5.1"
|
||||
paste = "1.0.14"
|
||||
png = "0.17.10"
|
||||
tool_helper = {path = "../tool_helper"}
|
|
@ -1,6 +1,35 @@
|
|||
pub mod types;
|
||||
|
||||
use std::io::Write;
|
||||
use tool_helper::{Error, Input};
|
||||
use types::MonoADPCMIterator;
|
||||
|
||||
pub fn convert(_input: Input, _output: &mut dyn Write) -> Result<(), Error> {
|
||||
pub fn convert(input: Input, _output: &mut dyn Write) -> Result<(), Error> {
|
||||
let mut wav_file = hound::WavReader::new(input)?;
|
||||
let wav_header = wav_file.spec();
|
||||
|
||||
validate(&wav_header)?;
|
||||
let mut sample_count = 0;
|
||||
for _adpcm_samples in MonoADPCMIterator::create(wav_file.samples::<i16>()) {
|
||||
sample_count += 1;
|
||||
}
|
||||
|
||||
println!("Parsed {} vag samples", sample_count);
|
||||
Err(Error::not_implemented("my vag convert"))
|
||||
}
|
||||
|
||||
fn validate(wav_header: &hound::WavSpec) -> Result<(), Error> {
|
||||
if wav_header.sample_format != hound::SampleFormat::Int {
|
||||
return Err(Error::from_str("VAG: Only integer samples are supported as input."));
|
||||
}
|
||||
|
||||
if wav_header.bits_per_sample != 16 {
|
||||
return Err(Error::from_str("VAG: Only 16bits samples are currently supported as input."));
|
||||
}
|
||||
|
||||
if wav_header.channels != 1 {
|
||||
return Err(Error::from_str("VAG: Only mono samples are currently supported"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
use tool_helper::Error;
|
||||
|
||||
pub struct VAGADPCM {
|
||||
data: [u32; 4]
|
||||
}
|
||||
|
||||
impl VAGADPCM {
|
||||
const ADPCM_SAMPLES_PER_VAGADPCM:usize = 28;
|
||||
|
||||
pub fn create() -> VAGADPCM {
|
||||
VAGADPCM{data: [0; 4]}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MonoADPCMIterator<I: std::iter::Iterator<Item=Result<i16, hound::Error>>> {
|
||||
iter: I
|
||||
}
|
||||
|
||||
impl<I:std::iter::Iterator<Item=Result<i16, hound::Error>>> MonoADPCMIterator<I>{
|
||||
pub fn create(iter: I) -> MonoADPCMIterator<I> {
|
||||
MonoADPCMIterator{iter}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I:std::iter::Iterator<Item=Result<i16, hound::Error>>> std::iter::Iterator for MonoADPCMIterator<I> {
|
||||
type Item = Result<[i16; VAGADPCM::ADPCM_SAMPLES_PER_VAGADPCM], Error>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
const STREAM_GONE_ERROR: &'static str = "Reading ADPCM sample failed";
|
||||
|
||||
if let Some(next_sample) = self.iter.next() {
|
||||
let Ok(next_sample) = next_sample else {return Some(Err(Error::from_str(STREAM_GONE_ERROR)));};
|
||||
|
||||
let mut sample = [0;VAGADPCM::ADPCM_SAMPLES_PER_VAGADPCM];
|
||||
sample[0] = next_sample;
|
||||
|
||||
for idx in 1..VAGADPCM::ADPCM_SAMPLES_PER_VAGADPCM {
|
||||
let Ok(next_sample) = self.iter.next().unwrap_or(Ok(0)) else {return Some(Err(Error::from_str(STREAM_GONE_ERROR)));};
|
||||
sample[idx] = next_sample;
|
||||
}
|
||||
return Some(Ok(sample));
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue