Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sinshu/rustysynth
A SoundFont MIDI synthesizer written in pure Rust
https://github.com/sinshu/rustysynth
audio meltysynth midi rust soundfont synthesizer
Last synced: 3 days ago
JSON representation
A SoundFont MIDI synthesizer written in pure Rust
- Host: GitHub
- URL: https://github.com/sinshu/rustysynth
- Owner: sinshu
- License: other
- Created: 2022-09-19T06:55:33.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-10-19T00:32:30.000Z (2 months ago)
- Last Synced: 2024-12-14T18:04:06.949Z (10 days ago)
- Topics: audio, meltysynth, midi, rust, soundfont, synthesizer
- Language: Rust
- Homepage:
- Size: 1 MB
- Stars: 145
- Watchers: 4
- Forks: 23
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# RustySynth
RustySynth is a SoundFont MIDI synthesizer written in pure Rust, ported from [MeltySynth](https://github.com/sinshu/meltysynth).
## Features
* Suitable for both real-time and offline synthesis.
* Supports standard MIDI files with additional features including dynamic tempo changing.
* No dependencies other than the standard library.## Demo
This is a demo video to show the synthesizer running on [rust-sfml](https://github.com/jeremyletang/rust-sfml) in real-time.
https://www.youtube.com/watch?v=o9rPTJIPmVk
[![Youtube video](rustysynth-yt.png)](https://www.youtube.com/watch?v=o9rPTJIPmVk)
## Installation
RustySynth is available on [crates.io](https://crates.io/crates/rustysynth):
```
cargo add rustysynth
```## Examples
An example code to synthesize a simple chord:
```rust
// Load the SoundFont.
let mut sf2 = File::open("TimGM6mb.sf2").unwrap();
let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap());// Create the synthesizer.
let settings = SynthesizerSettings::new(44100);
let mut synthesizer = Synthesizer::new(&sound_font, &settings).unwrap();// Play some notes (middle C, E, G).
synthesizer.note_on(0, 60, 100);
synthesizer.note_on(0, 64, 100);
synthesizer.note_on(0, 67, 100);// The output buffer (3 seconds).
let sample_count = (3 * settings.sample_rate) as usize;
let mut left: Vec = vec![0_f32; sample_count];
let mut right: Vec = vec![0_f32; sample_count];// Render the waveform.
synthesizer.render(&mut left[..], &mut right[..]);
```Another example code to synthesize a MIDI file:
```rust
// Load the SoundFont.
let mut sf2 = File::open("TimGM6mb.sf2").unwrap();
let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap());// Load the MIDI file.
let mut mid = File::open("flourish.mid").unwrap();
let midi_file = Arc::new(MidiFile::new(&mut mid).unwrap());// Create the MIDI file sequencer.
let settings = SynthesizerSettings::new(44100);
let synthesizer = Synthesizer::new(&sound_font, &settings).unwrap();
let mut sequencer = MidiFileSequencer::new(synthesizer);// Play the MIDI file.
sequencer.play(&midi_file, false);// The output buffer.
let sample_count = (settings.sample_rate as f64 * midi_file.get_length()) as usize;
let mut left: Vec = vec![0_f32; sample_count];
let mut right: Vec = vec![0_f32; sample_count];// Render the waveform.
sequencer.render(&mut left[..], &mut right[..]);
```Yet another example code to synthesize a MIDI file in real-time with [TinyAudio](https://github.com/mrDIMAS/tinyaudio):
```rust
// Setup the audio output.
let params = OutputDeviceParameters {
channels_count: 2,
sample_rate: 44100,
channel_sample_count: 4410,
};// Buffer for the audio output.
let mut left: Vec = vec![0_f32; params.channel_sample_count];
let mut right: Vec = vec![0_f32; params.channel_sample_count];// Load the SoundFont.
let mut sf2 = File::open("TimGM6mb.sf2").unwrap();
let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap());// Load the MIDI file.
let mut mid = File::open("flourish.mid").unwrap();
let midi_file = Arc::new(MidiFile::new(&mut mid).unwrap());// Create the MIDI file sequencer.
let settings = SynthesizerSettings::new(params.sample_rate as i32);
let synthesizer = Synthesizer::new(&sound_font, &settings).unwrap();
let mut sequencer = MidiFileSequencer::new(synthesizer);// Play the MIDI file.
sequencer.play(&midi_file, false);// Start the audio output.
let _device = run_output_device(params, {
move |data| {
sequencer.render(&mut left[..], &mut right[..]);
for (i, value) in left.iter().interleave(right.iter()).enumerate() {
data[i] = *value;
}
}
})
.unwrap();// Wait for 10 seconds.
std::thread::sleep(std::time::Duration::from_secs(10));
```## Todo
* __Wave synthesis__
- [x] SoundFont reader
- [x] Waveform generator
- [x] Envelope generator
- [x] Low-pass filter
- [x] Vibrato LFO
- [x] Modulation LFO
* __MIDI message processing__
- [x] Note on/off
- [x] Bank selection
- [x] Modulation
- [x] Volume control
- [x] Pan
- [x] Expression
- [x] Hold pedal
- [x] Program change
- [x] Pitch bend
- [x] Tuning
* __Effects__
- [x] Reverb
- [x] Chorus
* __Other things__
- [x] Standard MIDI file support
- [x] MIDI file loop extension support
- [x] Performace optimization## License
RustySynth is available under [the MIT license](LICENSE.txt).