Skip to content

Instantly share code, notes, and snippets.

@kujirahand
Created July 14, 2023 10:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kujirahand/d19be133cc227d2312d9e3b27b55ab39 to your computer and use it in GitHub Desktop.
Save kujirahand/d19be133cc227d2312d9e3b27b55ab39 to your computer and use it in GitHub Desktop.
SoundFontを使ったMIDIプレイヤー
//
// cargo add rustysynth
// cargo add wav_io
use rustysynth::{SynthesizerSettings, Synthesizer, SoundFont, MidiFile, MidiFileSequencer};
use wav_io;
// 定数の指定 --- (*1)
const FILE_SOUNDFONT: &str = "TimGM6mb.sf2"; // サウンドフォントのパス
const FILE_MIDI: &str = "sakura2.mid"; // 入力MIDIファイルのパス
const FILE_WAV: &str = "sakura2.wav"; // 出力WAVファイルのパス
const SAMPLE_RATE: u32 = 44_100; // サンプリング周波数(CD音質)
fn main() {
// 用意したサウンドフォントを読み込む --- (*2)
let mut sf2 = std::fs::File::open(FILE_SOUNDFONT).unwrap();
let sound_font = std::sync::Arc::new(SoundFont::new(&mut sf2).unwrap());
// シンセサイザーの作成 --- (*3)
let settings = SynthesizerSettings::new(SAMPLE_RATE as i32);
let synthesizer = Synthesizer::new(&sound_font, &settings).unwrap();
// MIDIシーケンサーの作成 --- (*4)
let mut sequencer = MidiFileSequencer::new(synthesizer);
// MIDIファイルの読み込み --- (*5)
let mut mid = std::fs::File::open(FILE_MIDI).unwrap();
let midi_file = std::sync::Arc::new(MidiFile::new(&mut mid).unwrap());
let midi_time_len = midi_file.get_length();
// MIDIデータをオーディオ化するのに必要なサンプル数を計算 --- (*6)
let sample_count = (SAMPLE_RATE as f64 * midi_time_len) as usize;
// 書き込み先のバッファを確保 --- (*7)
let mut samples = vec![0.0f32; sample_count * 2];
let mut left_buf = vec![0.0f32; sample_count];
let mut right_buf = vec![0.0f32; sample_count];
// サウンドフォントを書き込み --- (*8)
sequencer.play(&midi_file, false);
sequencer.render(&mut left_buf[..], &mut right_buf[..]);
for i in 0..left_buf.len() {
samples[i*2+0] = left_buf[i];
samples[i*2+1] = right_buf[i];
}
// WAVファイルへ保存 --- (*9)
let mut wav_head = wav_io::new_stereo_header();
wav_head.sample_rate = SAMPLE_RATE;
let mut wav_out = std::fs::File::create(FILE_WAV).unwrap();
wav_io::write_to_file(&mut wav_out, &wav_head, &samples).unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment