■ WavWriter 구조체의 write_sample 메소드를 사용해 방형파(square wave)의 WAV 파일을 생성하는 방법을 보여준다.
▶ Cargo.toml
1 2 3 4 5 6 7 8 9 |
[package] name = "test_project" version = "0.1.0" edition = "2021" [dependencies] hound = "3.4.0" |
▶ src/main.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
use std::fs; use std::io; use hound; const SAMPLE_RATE : f32 = 44100.0; fn main() { let wav_spec : hound::WavSpec = hound::WavSpec { channels : 1, sample_rate : SAMPLE_RATE as u32, bits_per_sample : 32, sample_format : hound::SampleFormat::Float, }; let mut wave_writer : hound::WavWriter<io::BufWriter<fs::File>> = hound::WavWriter::create("d:/sq.wav", wav_spec).unwrap(); let mut wave_vector : Vec<f32> = vec![]; let bpm : usize = 120; [60, 64, 67, 64, 60, 64, 67, 72].iter().for_each ( |sacle : &i32| { wave_vector.extend(get_square_wave_vector(*sacle, calculate_note_length(bpm, 8), 0.5)); } ); for v in wave_vector.into_iter() { wave_writer.write_sample(v).unwrap(); } } // scale : 음계, 예) 60(도), 64(미), 67(솔) fn get_frequency(scale : i32) -> f32 { return 440.0 * 2.0f32.powf((scale - 69) as f32 / 12.0); } // bpm : 분당 박자, beats per minute // note : 음표 예) 4(4분 음표) fn calculate_note_length(bpm : usize, note : usize) -> usize { let base_length : f32 = (60.0 / bpm as f32) * SAMPLE_RATE; return ((4.0 / note as f32) * base_length) as usize; } // scale : 음계, 예) 60(도), 64(미), 67(솔) // note_length : 음표 길이 (샘플 수) // gain : 출력 fn get_square_wave_vector(scale : i32, note_length : usize, gain : f32) -> Vec<f32> { let frequency : f32 = get_frequency(scale); let interval : f32 = SAMPLE_RATE / frequency; let mut wave_vector :Vec<f32> = vec![0.0; note_length]; let half_frequency : usize = (interval / 2.0) as usize; for i in 0..note_length { let value : usize = (i / half_frequency) % 2; wave_vector[i] = if value == 0 { -1.0 } else { 1.0 }; } wave_vector.into_iter().map(|v| (v * gain) as f32).collect() } |