sinshu / rustysynth

A SoundFont MIDI synthesizer written in pure Rust
Other
140 stars 22 forks source link

Difficulties using set_pitch_bend #25

Closed agourlay closed 3 days ago

agourlay commented 4 days ago

I am using Rustysynth 1.3.1 to play guitar sound in https://github.com/agourlay/ruxguitar

In order to reproduce guitar bends, I am relying on set_pitch_bend via process_message.

synthesizer.process_midi_message(4, 224, 80, 0)

Here is an example of logging the events sent during a string bend in my application

Note on: channel=4, key=69, velocity=127
Midi message: channel=4, command=224, data1=80, data2=0
Midi message: channel=4, command=224, data1=80, data2=0
Midi message: channel=4, command=224, data1=79, data2=0
Midi message: channel=4, command=224, data1=78, data2=0
Midi message: channel=4, command=224, data1=77, data2=0
Midi message: channel=4, command=224, data1=76, data2=0
Midi message: channel=4, command=224, data1=75, data2=0
Midi message: channel=4, command=224, data1=74, data2=0
Midi message: channel=4, command=224, data1=73, data2=0
Midi message: channel=4, command=224, data1=72, data2=0
Midi message: channel=4, command=224, data1=71, data2=0
Midi message: channel=4, command=224, data1=70, data2=0
Midi message: channel=4, command=224, data1=69, data2=0
Midi message: channel=4, command=224, data1=68, data2=0
Midi message: channel=4, command=224, data1=67, data2=0
Midi message: channel=4, command=224, data1=66, data2=0
Midi message: channel=4, command=224, data1=65, data2=0
Midi message: channel=4, command=224, data1=64, data2=0
Midi message: channel=4, command=224, data1=64, data2=0
Midi message: channel=4, command=224, data1=64, data2=0
Midi message: channel=4, command=224, data1=64, data2=0
Note off: channel=4, key=69

However it seems to have no effect on the synthesized sound as I can only hear the note going on and off without change in pitch.

Am I missing something to make this work?

Thank you very much for this great library :+1:

sinshu commented 4 days ago

I'm glad if this library has been of any help 😊

In MIDI, pitch bend is specified with a value from 0 to 16383.

8192 corresponds to no bend, 0 to the maximum downward bend, and 16383 to the maximum upward bend. By default, specifying the maximum value bends the pitch by two semitones.

The tricky part is that the bend value must be split into two bytes and sent to the synthesizer. For example, if you want to bend up to the maximum, the code would look like this:

bend = 16383;
data1 = bend & 0x7F;
data2 = bend >> 7;
process_midi_message(0, 224, data1, data2);

If you send this data1 and data2 to the synthesizer using process_midi_message, the pitch should increase by two semitones. In your code, it seems data2 is becoming 0, which likely causes the bend amount to be very small.

If you want to bend the pitch by more than two semitones, you need to set the bend range. For example, with the following setting, you can bend up to one octave.

process_midi_message(0, 0xB0, 0x64, 0);
process_midi_message(0, 0xB0, 0x65, 0);
process_midi_message(0, 0xB0, 0x06, 12);
agourlay commented 3 days ago

Thank you very much for the fast and detailed answer! :clap: