audiowaveform 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/COPYING +674 -0
  3. data/Cargo.lock +1108 -0
  4. data/Cargo.toml +28 -0
  5. data/README.md +255 -0
  6. data/bindings/ruby/CHANGELOG.md +29 -0
  7. data/bindings/ruby/Cargo.lock +621 -0
  8. data/bindings/ruby/Cargo.toml +8 -0
  9. data/bindings/ruby/README.md +193 -0
  10. data/bindings/ruby/ext/audiowaveform/Cargo.toml +20 -0
  11. data/bindings/ruby/ext/audiowaveform/build.rs +4 -0
  12. data/bindings/ruby/ext/audiowaveform/extconf.rb +6 -0
  13. data/bindings/ruby/ext/audiowaveform/src/lib.rs +239 -0
  14. data/bindings/ruby/lib/audiowaveform/version.rb +5 -0
  15. data/bindings/ruby/lib/audiowaveform.rb +131 -0
  16. data/crates/audiowaveform/Cargo.toml +73 -0
  17. data/crates/audiowaveform/examples/generate_from_pcm.rs +25 -0
  18. data/crates/audiowaveform/examples/generate_waveform.rs +18 -0
  19. data/crates/audiowaveform/examples/render_waveform.rs +18 -0
  20. data/crates/audiowaveform/examples/resample_waveform.rs +19 -0
  21. data/crates/audiowaveform/src/audio.rs +938 -0
  22. data/crates/audiowaveform/src/color.rs +201 -0
  23. data/crates/audiowaveform/src/error.rs +89 -0
  24. data/crates/audiowaveform/src/format.rs +215 -0
  25. data/crates/audiowaveform/src/lib.rs +79 -0
  26. data/crates/audiowaveform/src/render.rs +802 -0
  27. data/crates/audiowaveform/src/wav.rs +95 -0
  28. data/crates/audiowaveform/src/waveform.rs +790 -0
  29. data/crates/audiowaveform/tests/formats.rs +223 -0
  30. data/crates/audiowaveform/tests/generate.rs +233 -0
  31. data/crates/audiowaveform/tests/render.rs +263 -0
  32. data/crates/audiowaveform/tests/support/mod.rs +125 -0
  33. data/crates/audiowaveform/tests/wav.rs +54 -0
  34. data/crates/audiowaveform/tests/waveform_io.rs +255 -0
  35. data/crates/audiowaveform-cli/Cargo.toml +43 -0
  36. data/crates/audiowaveform-cli/src/main.rs +803 -0
  37. data/crates/audiowaveform-cli/tests/cli.rs +483 -0
  38. data/crates/audiowaveform-cli/tests/support/mod.rs +111 -0
  39. data/sig/audiowaveform.rbs +33 -0
  40. metadata +100 -0
@@ -0,0 +1,95 @@
1
+ #[cfg(feature = "decode")]
2
+ use std::fs::File;
3
+ use std::io::Write;
4
+ #[cfg(feature = "decode")]
5
+ use std::io::{Read, Seek};
6
+ #[cfg(feature = "decode")]
7
+ use std::path::Path;
8
+
9
+ use hound::{SampleFormat, WavSpec, WavWriter};
10
+
11
+ #[cfg(feature = "decode")]
12
+ use crate::AudioFormat;
13
+ #[cfg(feature = "decode")]
14
+ use crate::audio::decode_audio_reader;
15
+ use crate::{Error, PcmAudio};
16
+
17
+ /// Writes interleaved PCM audio as a 16-bit WAV stream.
18
+ pub fn write_pcm_as_wav<W: Write>(pcm: &PcmAudio, mut writer: W) -> Result<(), Error> {
19
+ let spec = WavSpec {
20
+ channels: pcm.channels(),
21
+ sample_rate: pcm.sample_rate(),
22
+ bits_per_sample: 16,
23
+ sample_format: SampleFormat::Int,
24
+ };
25
+ let mut bytes = Vec::new();
26
+ {
27
+ let cursor = std::io::Cursor::new(&mut bytes);
28
+ let mut wav = WavWriter::new(cursor, spec)?;
29
+ for sample in pcm.samples() {
30
+ wav.write_sample(*sample)?;
31
+ }
32
+ wav.finalize()?;
33
+ }
34
+ writer.write_all(&bytes)?;
35
+ Ok(())
36
+ }
37
+
38
+ /// Decodes audio from a path and writes it as a WAV file.
39
+ #[cfg(feature = "decode")]
40
+ pub fn transcode_audio_path_to_wav_path(
41
+ input: impl AsRef<Path>,
42
+ output: impl AsRef<Path>,
43
+ ) -> Result<(), Error> {
44
+ let input = input.as_ref();
45
+ let format = AudioFormat::from_path(input).ok_or_else(|| Error::UnsupportedFormat {
46
+ format: input
47
+ .extension()
48
+ .and_then(|value| value.to_str())
49
+ .unwrap_or_default()
50
+ .to_string(),
51
+ })?;
52
+ let file = File::open(input)?;
53
+ let mut output_file = File::create(output)?;
54
+ transcode_audio_reader_to_wav_writer(file, Some(format), &mut output_file)
55
+ }
56
+
57
+ /// Decodes audio from a seekable reader and writes it as a WAV stream.
58
+ #[cfg(feature = "decode")]
59
+ pub fn transcode_audio_reader_to_wav_writer<R: Read + Seek + Send + Sync + 'static, W: Write>(
60
+ reader: R,
61
+ format_hint: Option<AudioFormat>,
62
+ writer: W,
63
+ ) -> Result<(), Error> {
64
+ let pcm = decode_audio_reader(reader, format_hint)?;
65
+ write_pcm_as_wav(&pcm, writer)
66
+ }
67
+
68
+ #[cfg(test)]
69
+ mod tests {
70
+ use std::io::Cursor;
71
+
72
+ use super::write_pcm_as_wav;
73
+ use crate::PcmAudio;
74
+
75
+ #[test]
76
+ fn writes_pcm_audio_as_valid_wav_bytes() {
77
+ let pcm = PcmAudio::new(44_100, 1, vec![0, 1, -1, 2, -2]).expect("pcm");
78
+ let mut wav = Vec::new();
79
+ write_pcm_as_wav(&pcm, &mut wav).expect("write wav");
80
+
81
+ assert_eq!(&wav[0..4], b"RIFF");
82
+ assert_eq!(&wav[8..12], b"WAVE");
83
+
84
+ let mut reader = hound::WavReader::new(Cursor::new(wav)).expect("read wav");
85
+ assert_eq!(reader.spec().channels, 1);
86
+ assert_eq!(reader.spec().sample_rate, 44_100);
87
+ assert_eq!(
88
+ reader
89
+ .samples::<i16>()
90
+ .collect::<Result<Vec<_>, _>>()
91
+ .expect("samples"),
92
+ vec![0, 1, -1, 2, -2]
93
+ );
94
+ }
95
+ }