diff --git a/docs/modulations/chanaft_polyaft.md b/docs/modulations/chanaft_polyaft.md index 3b037c17b..13c43cc2d 100644 --- a/docs/modulations/chanaft_polyaft.md +++ b/docs/modulations/chanaft_polyaft.md @@ -39,4 +39,4 @@ pitchlfo_depthpolyaft=33 [cutoff_polyaft]: ../opcodes/cutoff.md [pitchlfo_freqchanaft]: ../opcodes/pitchlfo_freq.md [first example]: ../opcodes/cutoff.md#examples -[SFZ1 LFO tutorial]: ../tutorials/sfz1_modulations.md#lfos-and-envelopes +[SFZ1 LFO tutorial]: ../tutorials/sfz-1-lfos.md diff --git a/docs/modulations/keytrack_veltrack.md b/docs/modulations/keytrack_veltrack.md index 2148454ea..c31f7b7fa 100644 --- a/docs/modulations/keytrack_veltrack.md +++ b/docs/modulations/keytrack_veltrack.md @@ -14,11 +14,11 @@ Note On MIDI messages provide For note number modulation, the suffix `_keytrack` is appended to the target. The target can be: -- amplifier (`amp`) -- filters (`fil` and `fil2`) -- pan position (`pan`) -- pitch (`pitch` or `tune`) -- start position in the sample (`position`) +- amplifier [(`amp`)][1] +- filters [(`fil` and `fil2`)][2] +- pan position [(`pan`)][3] +- pitch [(`pitch` or `tune`)][4] +- stereo field position of the sample [(`position`)][5] See the [opcode list] and search for `_keytrack` to see more. @@ -30,8 +30,18 @@ or random amount (appending `_random`). Again, see the [opcode list] and search for `_veltrack` to see more. -See the last of the [Velocity tracking, keytracking and randomization][1] examples. +For example: + +```sfz +gain_cc80=-6 +amp_keytrack=-1.3 +amp_veltrack=80 +``` [<curve>]: ../headers/curve.md [opcode list]: ../opcodes/index.md -[1]: ../tutorials/sfz1_modulations.md#velocity-tracking-keytracking-and-randomization +[1]: ../opcodes/volume.md +[2]: ../opcodes/cutoff.md +[3]: ../opcodes/pan.md +[4]: ../opcodes/pitch.md +[5]: ../opcodes/position.md \ No newline at end of file diff --git a/docs/modulations/midi_ccs.md b/docs/modulations/midi_ccs.md index 2a562a894..1c4ce6326 100644 --- a/docs/modulations/midi_ccs.md +++ b/docs/modulations/midi_ccs.md @@ -65,5 +65,5 @@ See also the related tutorials for [SFZ1] and [SFZ2]. [extended MIDI CCs]: ../extensions/midi_ccs.md [width]: ../opcodes/width.md [headers]: ../headers/index.md -[SFZ1]: ../tutorials/sfz1_modulations.md +[SFZ1]: ../tutorials/sfz-1-midiccs.md [SFZ2]: ../tutorials/sfz2_modulations.md diff --git a/docs/modulations/vel2.md b/docs/modulations/vel2.md index 866590b0f..5388b7f4f 100644 --- a/docs/modulations/vel2.md +++ b/docs/modulations/vel2.md @@ -1,25 +1,22 @@ --- -title: (eg type)_vel2(target) +title: (target)_vel2(param) Velocity Tracking --- -The __velocity_to__ modulations time, in seconds, can be calculated as: +## Envelope Generators -``` -(target) time = (eg type)_(target) + (eg type)_vel2(target) * velocity / 127 -``` - -and the sustain level, in percentage, as: +`ampeg`, `fileg` and `pitcheg` can have all their parameters modulated by note velocity. ``` -sustain level = (eg type)_sustain + (eg type)_vel2sustain +(param) = (eg type)_(param) + ( (eg type)_vel2(param) * velocity / 127 ) ``` -Range is -100 seconds to 100 seconds, but in most typical cases, the effect of -velocity on envelope delay and attack times will be negative, and the effect -of velocity on other envelope parameters positive. This would make a sound have -a faster attack and a slower decay when a note has higher velocity, with attack -of 0.5 seconds at 0 velocity and 0.1 seconds at 127 velocity: +Range is -100 seconds to 100 seconds or -100 to 100 percent but, in most typical cases, +the effect of velocity on envelope delay and attack times will be negative +and the effect of velocity on other envelope parameters positive. -``` +This would make a sound have a faster attack and a slower decay when a note has higher velocity, +with attack of 0.5 seconds at 0 velocity and 0.1 seconds at 127 velocity: + +```sfz ampeg_attack=0.5 ampeg_vel2attack=-0.4 ampeg_decay=0.5 @@ -28,6 +25,21 @@ ampeg_sustain=50 ampeg_release=0.25 ``` -## EQ +## EQ Bands -TODO +For the EQ parameters, the same calculation applies: + +``` +(param) = (eq band)_(param) + ( (eq band)_vel2(param) * velocity / 127 ) +``` + +To set up the EQ1 band at 880 HZ with a 6dB cut and half an octave bandwidth, +but allowing note velocity to adjust this by cutting the EQ midpoint by up to 110 Hz (at velocity 127) +and increasing the cut to -12dB (at velocity 127), you might write the following: +```sfz +eq1_bw=0.5 +eq1_freq=880 +eq1_gain=-6 +eq1_vel2freq=-110 +eq1_vel2gain=-6 +``` diff --git a/docs/opcodes/amplfo_delay.md b/docs/opcodes/amplfo_delay.md index 5d6da78b3..1bce4cdfc 100644 --- a/docs/opcodes/amplfo_delay.md +++ b/docs/opcodes/amplfo_delay.md @@ -2,12 +2,17 @@ template: "sfz/opcode.j2" opcode_name: "amplfo_delay" --- -## Examples +SFZ1 supports amplitude, filter and pitch LFOs, see [SFZ1 LFOs][1] for details. + +Delay itself is not a modulator - it simply adjust the time after +the voice is triggered that the LFO effect starts. +This is very useful, as many instruments and vocals don't trigger +vibrato immediately when a note starts, but slightly later. ```sfz -pitchlfo_delay=1 amplfo_delay=0.4 +fillfo_delay=6 +pitchlfo_delay=1 ``` -This is very useful, as many instruments and vocals don't trigger vibrato -immediately when a note starts, but slightly later. +[1]: ../tutorials/sfz-1-lfos.md diff --git a/docs/tutorials/sfz-1-egs.md b/docs/tutorials/sfz-1-egs.md new file mode 100644 index 000000000..3a850a07f --- /dev/null +++ b/docs/tutorials/sfz-1-egs.md @@ -0,0 +1,60 @@ +--- +title: SFZ1 EGs +--- + +Volume, filter and cutoff also each get an [LFO] and an envelope. + +Each envelope has seven parameters: + +- [delay][1] -- delay between the start of the voice and the EG taking effect +- [start][2] -- the initial level of the EG +- [attack][3] -- the duration of the attack phase of the EG +- [hold][4] -- .. hold phase +- [decay][5] -- .. decay phase +- [sustain][6] -- the level to which the EG decays +- [release][7] -- the duration of the release phase of the EG + +Each envelope parameter can also be modulated by [CC], or by [velocity]. + +SFZ1 offers no further control: for more complex requirements, see the [SFZ2 modulations]. + +Here's an example setup for a synth-style ADSR volume envelope +(hold is not specified so the default hold value of 0 is used) +controlled by CCs and some initial minimum values set for attack and release, +along with a default sustain of 0: + +```sfz +ampeg_attack=0.001 +ampeg_attackcc40=1 +ampeg_decaycc41=4 +ampeg_sustain=1 +ampeg_sustaincc42=100 +ampeg_release=0.1 +ampeg_releasecc43=0.9 +``` + +Modulating envelope parameters with velocity allows, for example, setting up a filter +on an acid bass which will sweep farther with higher velocity, and also sweep faster. + +```sfz +cutoff=120 +resonance=12 +fileg_attack=0.5 +fileg_decay=1 +fileg_depth=500 +fileg_vel2attack=-0.4 +fileg_vel2decay=-0.8 +fileg_vel2depth=4000 +``` + +[LFO]: sfz-1-lfos.md +[CC]: ../modulations/midi_ccs.md +[velocity]: ../modulations/vel2.md +[SFZ2 modulations]: sfz2_modulations.md +[1]: ../opcodes/ampeg_delay.md +[2]: ../opcodes/ampeg_start.md +[3]: ../opcodes/ampeg_attack.md +[4]: ../opcodes/ampeg_hold.md +[5]: ../opcodes/ampeg_decay.md +[6]: ../opcodes/ampeg_sustain.md +[7]: ../opcodes/ampeg_release.md diff --git a/docs/tutorials/sfz-1-lfos.md b/docs/tutorials/sfz-1-lfos.md new file mode 100644 index 000000000..9a0570446 --- /dev/null +++ b/docs/tutorials/sfz-1-lfos.md @@ -0,0 +1,52 @@ +--- +title: SFZ1 LFOs +--- + +Volume, filter and cutoff also each get an LFO and an [envelope]. + +Each LFO has four parameters: + +- [depth][1] -- the maximum degree of modulation applied to the target, in the units of the target +- [frequency][2] (`(lfo type)_freq`) -- specifies the cycle time in Hz (with negative values allowing inverse phase) +- [delay][3] -- the amount of time after the voice is triggered that the LFO starts applying its effect +- [fade][4] -- the time taken after the delay for the depth to reach maximum + +The rate and depth can be modulated by MIDI CC, channel aftertouch and polyphonic aftertouch. + +SFZ1 offers no further control: for more complex requirements, see the [SFZ2 modulations]. + +### Examples + +Here's a typical pitch vibrato LFO: + +```sfz +pitchlfo_freq=2 +pitchlfo_freqcc50=10 +pitchlfo_depthcc51=33 +``` + +To have amplitude modulation fade in over two seconds, after a delay of a second, then cycling by 3dB every 5 seconds: +```sfz +volume=-3 +amplfo_depth=3 +amplfo_freq=0.2 +amplfo_delay=1 +amplfo_fade=2 +``` + +To add a filter LFO, adjusting the filter cutoff, controlled by CC1, channel aftertouch and polyphonic aftertouch: +```sfz +cutoff=3520 +fillfo_depth=1200 +fillfo_depthcc1=-1200 +fillfo_freq=-0.1 +fillfo_freqchanaft=0.2 +fillfo_freqpolyaft=0.2 +``` + +[envelope]: sfz-1-egs.md +[1]: ../opcodes/amplfo_depth.md +[2]: ../opcodes/amplfo_freq.md +[3]: ../opcodes/amplfo_delay.md +[4]: ../opcodes/amplfo_fade.md +[SFZ2 modulations]: sfz2_modulations.md diff --git a/docs/tutorials/sfz-1-midiccs.md b/docs/tutorials/sfz-1-midiccs.md new file mode 100644 index 000000000..5ce7e0919 --- /dev/null +++ b/docs/tutorials/sfz-1-midiccs.md @@ -0,0 +1,54 @@ +--- +title: SFZ1 Basic MIDI CC modulations +--- + +The following SFZ1 opcodes can be modulated by MIDI CCs, with the value of +the MIDI CC adjusting the setting applied by the opcode +(0 to 127 mapped to the maximum set in the modulation). + +These opcode names have `_ccN` appended: + +- [delay][1] +- [offset][2] +- [gain][3] +- [cutoff][4] +- [resonance][5] + +Where the name is already more complex, in SFZ1, just `ccN` is appended: + +- (eg type)\_(eg parameter) -- see: ampeg, fileg and pitcheg parameters [delay][6], [start][7], [attack][8], [hold][9], [decay][10], [sustain][11] and [release][12]; for examples, see [the EGs page](sfz-1-egs.md) +- (lfo type)\_(depth or freq) -- see: amplfo, fillfo and pitchlfo parameters [depth][13] and [freq][14]; for examples, see [the LFOs page](sfz-1-lfos.md) +- (eq band)\_(eq parameter) -- see: eq 1 to 3 parameters [bw][15], [freq][16] and [gain][17] + +In all these cases except for [cutoff][4], the units match the opcode. +For [cutoff][4], the base opcode is in Hz whilst modulation is in cents. + +### Examples + +When triggered, the following causes a region to start playing a sample from offset 500. +("offset 0" would mean from the start - but note that some players use "offset 1" to play from the start.) +CC100 then allows an additional 500 samples of offset to be added (note that MIDI CCs only have 128 steps, so +this will not necessarily be smoothly interpolated), giving an offset of 1000 at maximum. + +```sfz +offset=500 +offset_cc100=500 +``` + +[1]: ../opcodes/delay_ccN.md +[2]: ../opcodes/offset_ccN.md +[3]: ../opcodes/gain_ccN.md +[4]: ../opcodes/cutoff_ccN.md +[5]: ../opcodes/resonance_ccN.md +[6]: ../opcodes/ampeg_delayccN.md +[7]: ../opcodes/ampeg_startccN.md +[8]: ../opcodes/ampeg_attackccN.md +[9]: ../opcodes/ampeg_holdccN.md +[10]: ../opcodes/ampeg_decayccN.md +[11]: ../opcodes/ampeg_sustainccN.md +[12]: ../opcodes/ampeg_releaseccN.md +[13]: ../opcodes/amplfo_depthccN.md +[14]: ../opcodes/amplfo_freqccN.md +[15]: ../opcodes/eqN_bwccX.md +[16]: ../opcodes/eqN_freqccX.md +[17]: ../opcodes/eqN_gainccX.md diff --git a/docs/tutorials/sfz1_modulations.md b/docs/tutorials/sfz1_modulations.md index 159f0c3a6..60549edfa 100644 --- a/docs/tutorials/sfz1_modulations.md +++ b/docs/tutorials/sfz1_modulations.md @@ -6,144 +6,93 @@ there's a dedicated opcode for every possible modulation, including fairly esoteric ones such as using note velocity to modulate the hold stage of the pitch envelope. +If something is not described below, then modulating it is not possible under the +SFZ1 specification, and will require [using SFZ2] or possibly some extension opcodes. + ## Basic MIDI CC modulation -A few opcodes can be modulated simply by MIDI CC, with the modulation adding -to what the opcode would normally do. These are: [offset] and [delay]. +For background, see [MIDI CC modulations] and for examples, see [SFZ 1 MIDI CC Examples][sfz-1-midiccs]. -For example, this would have a sample offset of 500 when the modulating CC is -at 0, and a sample offset of 1000 when the modulating CC is at max: +## Note Number and Velocity Tracking -```sfz -offset=500 -offset_cc100=500 -``` +Volume (`amp`), filter cutoff (`fil`) and pitch allow MIDI [Note Number][10] and [Velocity][11] +to be used to modulate the base opcode values using `_keytrack` and `_veltrack` respectively, +with the units matching the base opcode. -It's also possible to just specify the modulation, in which case the -default value is what will be modulated. The defaults for offset, delay and -EQ band gain are 0, so this would result in the offset being modulated between -0 and 1000: +An example is given in "[MIDI Note Number and Velocity tracking](../modulations/keytrack_veltrack.md)". -```sfz -offset_cc100=1000 -``` +## "vel2" velocity tracking -## Modulating default values +The three SFZ1 envelope generators (ampeg, fileg and pitcheg) along with the three SFZ1 equalizer bands (EQ1 to 3) +allow parameters to be modulated by the initial note on velocity using `(target)_vel2(param)` syntax. -The three EQ bands' [frequency][1], [bandwidth] and [gain][2] work similarly, -but also add velocity tracking. The EQ bandwidth and center frequency also have -non-zero defaults, -for example eq2_freq is 500 if not specified. So, this would modulate the center -frequency of the second EQ band between 500 and 1500 if eq2_freq is left at default: +This is explained in more detail, with examples, in "[(target)\_vel2(param) Velocity Tracking](../modulations/vel2.md)". -```sfz -eq2_freqcc110=1000 -``` +## Controlled adjustment -## Velocity tracking, keytracking and randomization +Volume, filter and cutoff also each get an [LFO] and an [envelope], for which +separate pages exist with examples. -EQ [frequency][3] and [gain][4] (but not bandwidth) can additionally be modulated by velocity. -For example, if we want to make a sound brighter when the velocity is higher, -we might use something like this: +## Random adjustment -```sfz -eq1_vel2gain=-6 -eq2_vel2gain=12 -eq2_vel2freq=500 -``` +[Filter cutoff][1], [delay][2], [volume][4], [offset][5] and [pitch][6] +all support random adjustment by appending `_random` to the opcode. -The [xfin]/[xfout] CCs are also a way to fade sounds in and out using MIDI CC. -An example of one note with two dynamic layers being crossfaded: +For example, the following gives 1dB of headroom which is randomly boosted into: ```sfz -sample=e4_ft_p.wav xfin_locc1=0 xfin_hicc1=63 xfout_locc1=64 xfout_hicc1=127 -sample=e4_ft_f.wav xfin_locc1=64 xfin_hicc1=127 +volume=-1 +amp_random=1 ``` -In addition to MIDI CC, crossfades can also use MIDI note number and velocity as -modulation sources, and the [xf_cccurve], [xf_keycurve] and [xf_velcurve] -give the choice of two curves for each of these modulations. +## Cross fading -More sophisticated modulations are possible with volume, -pitch and [filter cutoff]. Volume and cutoff can be modulated by MIDI CC directly -(pitch can't in SFZ1 - the tune_ccN modulation is an ARIA extension). All three -can also have randomization applied and be modulated by MIDI note number and -velocity. The nomenclature for volume is a little confusing, with [gain_ccN] using -"gain" in the name, while the others are called [amp_random], -[amp_keytrack] and [amp_veltrack]. +Cross fading can also be considered a form of modulation. +This is where two overlapping voices are faded into one another. +The overlapping voices can be controlled by: -```sfz -gain_cc80=-6 -amp_random=3 -amp_keytrack=-1.3 -amp_veltrack=80 -``` +- MIDI CC number value range [(`ccN`)][7] +- note number range [(`key`)][8] +- note velocity range [(`vel`)][9] -## LFOs and envelopes +In each case, there is a `xfin_lo/xfin_hi` and `xfout_lo/xfout_hi` pair for +[`ccN`][7], [`key`][8], [`vel`][9]. -Volume, filter and cutoff also each get an [LFO] and an [envelope]. -The LFO rate and depth can be modulated by MIDI CC. -Each LFO also has a simple envelope with delay and fade, -but modulating the duration of these is not allowed under the SFZ1 spec -(though it is with SFZ2 LFOs). Here's a typical pitch vibrato LFO: +An example of one note with two dynamic layers being cross faded: ```sfz -pitchlfo_freq=2 -pitchlfo_freqcc50=10 -pitchlfo_depthcc51=33 + +sample=e4_ft_p.wav +xfin_locc1=0 xfin_hicc1=63 +xfout_locc1=64 xfout_hicc1=127 + + +sample=e4_ft_f.wav +xfin_locc1=64 xfin_hicc1=127 ``` -Each envelope parameter can also be modulated by CC, or by velocity. Here's a -exmple setup for a synth-style ADSR volume envelope (hold is not specified so the -default hold value of 0 is used) controlled by CCs and some initial -minimum values set for attack and release, along with a default sustain of 0: +The [xf_cccurve], [xf_keycurve] and [xf_velcurve] opcodes +give the choice of two curves for each cross fade type: -```sfz -ampeg_attack=0.001 -ampeg_attack_oncc40=1 -ampeg_decay_oncc41=4 -ampeg_sustain=1 -ampeg_sustain_oncc42=100 -ampeg_release=0.1 -ampeg_release_oncc43=0.9 -``` - -Modulating envelope parameters with velocity allows, for example, setting up a filter -on an acid bass which will sweep farther with higher velocity, and also sweep faster. - -```sfz -cutoff=120 -resonance=12 -fileg_attack=0.5 -fileg_decay=1 -fileg_depth=500 -fileg_vel2attack=-0.4 -fileg_vel2decay=-0.8 -fileg_vel2depth=4000 -``` +- **gain**: Linear gain crossfade. This setting is best when crossfading phase-aligned material. Linear gain crossfades keep constant amplitude during the crossfade, preventing clipping. +- **power**: Equal-power RMS crossfade. This setting works better when mixing very different material, as a constant power level is kept during the crossfade. -If something is not described above, then modulating it is not possible under the -SFZ1 specification, and will require [using SFZ2] or possibly some extension opcodes. - - -[using SFZ2]: sfz2_modulations.md [modulations]: ../modulations/index.md -[envelope]: ../modulations/envelope_generators.md#sfz-1-egs -[LFO]: ../modulations/lfo.md#sfz-1-lfos -[amp_keytrack]: ../opcodes/amp_keytrack.md -[amp_random]: ../opcodes/amp_random.md -[amp_veltrack]: ../opcodes/amp_veltrack.md -[bandwidth]: ../opcodes/eqN_bw.md -[delay]: ../opcodes/delay.md -[filter cutoff]: ../opcodes/cutoff.md -[gain_ccN]: ../opcodes/volume.md -[offset]: ../opcodes/offset.md +[using SFZ2]: sfz2_modulations.md +[MIDI CC modulations]: ../modulations/midi_ccs.md +[sfz-1-midiccs]: sfz-1-midiccs.md +[LFO]: sfz-1-lfos.md +[envelope]: sfz-1-egs.md +[1]: ../opcodes/fil_random.md +[2]: ../opcodes/delay_random.md +[4]: ../opcodes/amp_random.md +[5]: ../opcodes/offset_random.md +[6]: ../opcodes/pitch_random.md +[7]: ../opcodes/xfin_loccN.md +[8]: ../opcodes/xfin_lokey.md +[9]: ../opcodes/xfin_lovel.md +[10]: ../opcodes/amp_keytrack.md +[11]: ../opcodes/amp_veltrack.md [xf_cccurve]: ../opcodes/xf_cccurve.md [xf_keycurve]: ../opcodes/xf_keycurve.md [xf_velcurve]: ../opcodes/xf_velcurve.md -[xfin]: ../opcodes/xfin_loccN.md -[xfout]: ../opcodes/xfout_loccN.md -[1]: ../opcodes/eqN_freq.md -[2]: ../opcodes/eqN_gain.md -[3]: ../opcodes/eqN_vel2freq.md -[4]: ../opcodes/eqN_vel2gain.md