rs_audio/wav/
exporter.rs

1use std::{
2    fs::File,
3    io::{BufReader, Error},
4};
5
6use hound::{WavSpec, WavWriter};
7use rodio::{Decoder, OutputStream, Sink};
8
9use crate::{waveform::generate_sample, BasicSong};
10
11impl BasicSong {
12    /**
13    # Deprecated
14    This feature has been deprecated in the latest update. Please use the new player, not the legacy one.<br><br>
15
16
17    Exports a Song struct to a .wav file.<br>It creates a .wav file in the current directory.<br>
18    Usage:
19    ```
20    use rs_audio::*;
21    use rs_audio::{legacyplayer::BasicSong};
22
23    let song = BasicSong::default();
24    song.export_to_wav("test.wav".to_string());
25    ```
26    */
27    pub fn export_to_wav(&self, filename: String) -> Result<(), Box<dyn std::error::Error>> {
28        // set up wave file specs
29        let spec = WavSpec {
30            channels: 1,
31            sample_rate: 44100,  // 44.1k Hz
32            bits_per_sample: 16, // 16 bit depth
33            sample_format: hound::SampleFormat::Int,
34        };
35
36        // create writer for writing to files
37        let mut writer = match WavWriter::create(filename, spec) {
38            Ok(e) => e,
39            Err(e) => {
40                eprintln!("RS-AUDIO: Error while creating file: {e}");
41                std::process::exit(1);
42            }
43        };
44
45        for note in &self.notes {
46            let total_samples = (note.dur * 44100.0) as usize;
47            for i in 0..total_samples {
48                let phase = (i as f64 * note.freq / 44100.0) % 1.0; // generate phase
49                let sample = generate_sample(&note.wave, phase) * note.vol as f64; // generate sample from waveform
50                writer.write_sample((sample * i16::MAX as f64) as i16)?; // add the sample
51            }
52        }
53
54        writer.finalize()?;
55
56        Ok(())
57    }
58
59    /**
60    # Deprecated
61    This feature has been deprecated in the latest update. Please use the new player, not the legacy one.<br><br>
62
63    Plays a .wav file.<br><br>
64
65
66    Usage:
67    ```
68    use rs_audio::*;
69    use rs_audio::{legacyplayer::BasicSong};
70
71    BasicSong::play_wav("test.wav").unwrap();
72    ```
73
74    */
75    pub fn play_wav(file_path: &str) -> Result<(), Error> {
76        let (_stream, handle) = OutputStream::try_default().unwrap();
77
78        let sink = match Sink::try_new(&handle) {
79            Ok(e) => e,
80
81            /* convert PlayError to std::io::Error */
82            Err(e) => return Err(Error::other(e.to_string())),
83        };
84
85        let file = File::open(file_path)?;
86        let source = Decoder::new(BufReader::new(file)).unwrap();
87
88        sink.append(source);
89        sink.sleep_until_end(); // blocks thread until finished
90
91        Ok(())
92    }
93}