0

How can you make one file, for example: "out.wav", and in it add "1.wav" 10 times, but without delays. That is, to superimpose the sound on another sound even if the previous one has not finished playing. As I've been trying to do for about an hour and a half now, and all I get is playback one by one (i.e.: first the sound plays completely)

Simplest code:

use hound::{WavReader, WavWriter};

fn main() {
    let mut reader = WavReader::open("1.wav").unwrap();
    let spec = reader.spec();
    let mut writer = WavWriter::create("output.wav", spec).unwrap();

    for _ in 0..10 {
        for sample in reader.samples::<i16>() {
            writer.write_sample(sample.unwrap()).unwrap();
        }

        reader.seek(0).unwrap();
    }
}
Inears
  • 3
  • 2

1 Answers1

0

You have to somehow read & mix the multiple sounds you want to play at the same time.

Here is an example that plays 10 times the same sound each delayed by half that sounds length, mixed by simply averaging both clips playing at the same time.

use hound::{WavReader, WavWriter};

fn main() {
    let mut reader = WavReader::open("1.wav").unwrap();
    let mut reader2 = WavReader::open("1.wav").unwrap();
    let mut writer = WavWriter::create("output.wav", spec).unwrap();
    let l = reader.len();
    reader.seek(l/2).unwrap();
    for i in 0..l*10 {
        if i % (l/2) == 0 {
            reader.seek(0).unwrap();
            let tmp = reader;
            reader = reader2;
            reader2 = tmp;
        }
        let s1 = reader.samples::<i16>().next().unwrap().unwrap();
        let s2 = reader2.samples::<i16>().next().unwrap().unwrap();
        let sample = s1/2 + s2/2;
        writer.write_sample(sample).unwrap();
    }
}

Which can definitely be cleaned up a lot (ie store the samples in a Vec once and just read from there)

cafce25
  • 15,907
  • 4
  • 25
  • 31
  • Thank you for your reply. Yes, this code plays 10 sounds in a row, but I still don't understand how to get the proper result, that is to play 10 sounds in a row. Like, "hound" still waits for the end of the audio, then adds another file – Inears Nov 30 '22 at 23:06
  • No, this code will start playing the second sample half way through the first one. For simplicity I start the first sample at half duration though. The main point is `hound` doesn't do any mixing, you'll have to do it (`sample = s1/2 + s2/2`) – cafce25 Nov 30 '22 at 23:15