Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

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

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).