-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Very initial version, just writing stuff down while it's fresh in my mind.
- Loading branch information
Showing
1 changed file
with
187 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
--- | ||
title: Sympathetic Resonance | ||
--- | ||
|
||
## Basics | ||
|
||
Many instruments have elements which will resonate after a note is stopped. A piano | ||
with the sustain pedal down is an obvious example. In sampled instruments, this is | ||
usually dealt with by recording one set of pedal-up samples and one set of | ||
pedal-down samples. Some sampled pianos will also support half-pedaling, though this | ||
will have to be documented later. | ||
|
||
The current version of this tutorial is based on an implementation of sympathetic | ||
resonance for a nyckelharpa, which is, more or less, a violin with a key mechanism | ||
and a set of 12 sympathetic strings. This was also reused for another instrument | ||
with a smaller number of diatonic sympathetic strings. | ||
|
||
The basic concept is simple: when a sustained note ends, a sympathetic resonance | ||
sample is played as a release sample. In the case of the nyckelharpa, the resonance | ||
samples were created by using only the tails of short notes. There is a set of | ||
round robin samples for each pitch, and they are mapped to the keys as normal. | ||
|
||
```sfz | ||
<master> | ||
#include "modules/maps/strings/nh/nh_sus_f_map.sfz" | ||
<master> | ||
trigger=release | ||
ampeg_attack=0.1 | ||
#include "modules/maps/strings/nh/nh_release_map.sfz" | ||
``` | ||
|
||
Instead of creating a separate set of samples it's even possible to simply use the | ||
shorts samples with an offset, if the shorts are performed consistently enough. | ||
|
||
```sfz | ||
<master> | ||
#include "modules/maps/strings/nh/nh_sus_f_map.sfz" | ||
<master> | ||
trigger=release | ||
ampeg_attack=0.1 | ||
offset=6600 | ||
#include "modules/maps/strings/nh/nh_short_map.sfz" | ||
``` | ||
|
||
## Controls | ||
|
||
We can add a simple volume control. | ||
|
||
```sfz | ||
<master> | ||
#include "modules/maps/strings/nh/nh_sus_f_map.sfz" | ||
<master> | ||
trigger=release | ||
ampeg_attack=0.1 | ||
amplitude_oncc52=100 | ||
locc52=1 | ||
#include "modules/maps/strings/nh/nh_release_map.sfz" | ||
``` | ||
|
||
To prevent the buildup of voices with fast playing, a polyphony group can be | ||
used. | ||
|
||
```sfz | ||
<master> | ||
#include "modules/maps/strings/nh/nh_sus_f_map.sfz" | ||
<master> | ||
trigger=release | ||
ampeg_attack=0.1 | ||
amplitude_oncc52=100 | ||
locc52=1 | ||
off_time=0.4 | ||
group=14 | ||
note_polyphony=1 | ||
#include "modules/maps/strings/nh/nh_release_map.sfz" | ||
``` | ||
|
||
## Multiple articulations | ||
|
||
There could be a separate set of resonance samples captured for each technique, but | ||
in practice one set of samples cut from shorts works reasonably well for most. | ||
However, tremolo seemed to agitate all the strings more. In other words, playing an | ||
A didn't just make the A and a little E resonate, even the A# and G# strings | ||
resonated a bit, perhaps as a result of the whole instrument shaking a bit. So, | ||
tremolo got its own set of samples. | ||
|
||
Shorts and pizzicato didn't use separate resonance samples, they were simply set | ||
to one-shot mode, so the entire sample played, resonance and all. This has its | ||
downsides, of course, but again it seems to work well enough in reality. | ||
|
||
However, with the jete technique, the same set of samples was used with the | ||
addition of rt_decay. Keeping it simple, here is the polyphonic implementation: | ||
|
||
```sfz | ||
<master> | ||
#include "modules/maps/strings/nh/nh_jete_map.sfz" | ||
<master> | ||
trigger=release | ||
off_time=0.4 | ||
rt_decay=12 | ||
ampeg_attack=0.1 | ||
#include "modules/maps/strings/nh/nh_release_map.sfz" | ||
``` | ||
|
||
## Legato | ||
|
||
The above works fine for polyphonic instruments, but with a mono instrument it's | ||
not enough to have a sample play on release; we also need to play a sample when | ||
a note is muted and a new note starts playing. At that point, we need to trigger | ||
the resonance based not on the incoming MIDI note but based on the previous pitch | ||
that was playing. | ||
|
||
```sfz | ||
//Mono mode | ||
<master> | ||
group=1 | ||
off_by=1 | ||
#include "modules/maps/strings/nh/nh_sus_f_map.sfz" | ||
//Mono mode, keypress restrictions so only triggered on last note of phrase | ||
<master> | ||
trigger=release | ||
amplitude_oncc52=200 | ||
locc52=1 | ||
off_time=0.4 | ||
ampeg_attack=0.1 | ||
group=14 | ||
note_polyphony=1 | ||
//Trigger only when one key was down | ||
lohdcc153=0 | ||
hihdcc153=1.1 | ||
//To keep from over-triggering when unison is on | ||
group=199 | ||
note_polyphony=1 | ||
#include "modules/maps/strings/nh/nh_release_map.sfz" | ||
//Mono mode, legato triggers | ||
//Loop mode is one shot to keep these from dying when the next key is released | ||
<master> | ||
trigger=legato | ||
amplitude_oncc52=200 | ||
locc52=1 | ||
locc105=64 | ||
off_time=0.4 | ||
ampeg_attack=0.1 | ||
loop_mode=one_shot | ||
pitch_keytrack=0 | ||
#include "modules/maps/strings/nh/nh_release_swdown_map.sfz" | ||
``` | ||
|
||
## Multiple voices | ||
|
||
When one key triggers multiple samples, whether they are crossfaded dynamic layers, | ||
mic posotions or unison voices, each sample playing is a voice which can trigger | ||
a release. In other words, with four mic positions having four sets of releases, | ||
sixteen release voices would be triggered for each note. This not only uses up | ||
unison voices but also is too loud and doesn't sound good. Fortunately this is | ||
easily fixed by creating a separate polyphony group for each voice's releases, | ||
and limiting its note polyphony. If groups are already created as discussed above, | ||
just make sure each set of samples has its own group number. | ||
|
||
This is not a consideration limited to sympathetic resonance, of course, but a | ||
general principle of using release triggers with multiple voices. | ||
|
||
```sfz | ||
<master> | ||
trigger=release | ||
ampeg_attack=0.1 | ||
//To keep from over-triggering when unison is on | ||
group=199 | ||
note_polyphony=1 | ||
#include "modules/maps/strings/nh/nh_release_map.sfz" | ||
``` | ||
|
||
## Other methods | ||
|
||
At least in theory, a better way to do this would be to capture an impulse response | ||
of the resonance, perhaps by giving the instrument a whack and letting the | ||
sympathetic strings ring. However, this would require an sfz player with | ||
convolution reverb implemented. |