ruuda / hound

A wav encoding and decoding library in Rust
https://codeberg.org/ruuda/hound
Apache License 2.0
482 stars 63 forks source link

Convert from 16bit to 24bit fail #69

Closed moyang628 closed 10 months ago

moyang628 commented 10 months ago

Hello

I try to convert 16bit wav to 24bit wav use this crate, the convert file can be generated as 24bit wav file. but there is no sound when I play the generated wav file. and I try to convert 32bit to 24bit ,it is a big noise wav file.

Is there some wrong??

the code:

use std::path::Path;
use std::{fs, i16, io};

use hound::{SampleFormat, WavSpec, WavSpecEx, WavWriter};

extern crate hound;

fn main() {
    let path: &Path = "chn_1.wav".as_ref();
    let mut reader = hound::WavReader::open(path).unwrap();
    let spec = reader.spec();
    println!("{:?}", spec);

    let samples: Vec<i16> = reader.samples().map(|s| s.unwrap()).collect();

    // println!("{:?}",samples);

    let new_path: &Path = "chn_1_resample.wav".as_ref();

    // let mut buffer = io::Cursor::new(Vec::new());
    let file: fs::File = fs::File::create(new_path).unwrap();
    let mut buf_writer = io::BufWriter::new(file);
    let spec = WavSpecEx {
        spec: WavSpec {
            channels: 2,
            sample_rate: 48000,
            bits_per_sample: 24,
            sample_format: SampleFormat::Int,
        },
        bytes_per_sample: 3,
    };

    let mut writer = WavWriter::new_with_spec_ex(&mut buf_writer, spec).unwrap();
    for sample in samples {
        let _ = writer.write_sample(sample);
    }

    writer.finalize().unwrap();

}
ruuda commented 10 months ago

Your code takes the 16 bit samples and reinterprets them as 24 bit samples without a shift. This means that a wave of maximum amplitude in 16 bits, would be at 1/256 of the maximum amplitude in 24 bits, making it sound silent. If you left-shift by 8 bits before writing the samples, that should resolve your issue. Be careful to widen the i16 sample to i32 before doing the shift.

Similar for 32 to 24 bits, you'd have to right shift by 8 bits and explicitly discard the additional information.

moyang628 commented 10 months ago

i got it,thanks