Pedal control - davidpanderson/Numula GitHub Wiki
Numula lets you control MIDI pedals (sustain, sostenuto, soft), including fractional pedaling. It also provides "virtual sustain pedals" which affect only a specified subset of notes.
All pedal operations on a Score
must precede timing adjustments.
MIDI pedals
Software piano synthesizers typically provide access (via MIDI) to three "pedals":
-
The sustain pedal lifts the dampers so that notes continue to sound after the key is released, and strings vibrate sympathetically.
-
The sostenuto pedal lifts the dampers of notes whose keys are down at the time the pedal is depressed.
-
The soft pedal lowers the volume and/or softens the timbre of all notes.
Some synthesizers (including Pianoteq) support partially lowering a pedal; for example, a half-lowered sustain pedal only partly damps the strings.
The MIDI pedal types are represented by:
PEDAL_SUSTAIN = 64
PEDAL_SOSTENUTO = 66
PEDAL_SOFT = 67
The class PedalSeg
represents an application of a pedal.
from numula.nscore import *
p = PedalSeg(
dur: float,
level0 = 1, level1 = 1,
closed_start = True, closed_end = True
)
Parameters:
time
: when the pedal is depressed (score time).dur
: how long the pedal remains depressed (score time).level0
,level1
: the levels of pedal depression (0 to 1) at the start and end of the interval. The level varies linearly between these.closed_start
: the pedal is applied before notes at the start time.closed_end
: the pedal is lifted after notes at the end time.pedal_type
: the pedal type.
A "pedal PFT" is a list of these segments.
To apply a PFT for MIDI pedal to a Score
starting at a given time:
Score.pedal_pft(pft: PFT, type: int = PEDAL_SUSTAIN, t0: float=0)
These PFTs can be created using a shorthand notation.
You can also add a single PedalSeg
to a Score
at a given time:
Score.insert_pedal(pedal: PedalSeg, type: int = PEDAL_SUSTAIN, t0: float)
If P0 and P1 are adjacent PedalSeg
objects
and there are notes that start at P1.time,
the semantics are:
P0.closed_end | P1.closed_start | result |
---|---|---|
false | false | release pedal, play notes, set pedal to p1.level0 |
false | true | release pedal, set pedal to p1.level0, play notes |
true | false | play notes, set pedal to p1.level0 |
true | true | set pedal to p1.level0, play notes |
If P0.closed_end
is set, the pedal is momentarily released,
and all notes being sustained by the pedal stop sounding.
Virtual sustain pedal
Numula provides a "virtual sustain pedal" feature, which is like the MIDI sustain pedal except that affects only a subset of notes. For example, a virtual pedal might apply to the LH but not the RH.
To use a virtual sustain pedal:
Score.sustain(t0: float, t1: float, selector: Selector=None)
For each selected note starting at t0
or later:
if the end time is before t1
,
change the duration so that the end time is t1
.
You can control virtual sustain pedals using a PFT
consisting of PedalSeg
objects.
When such a PFT is used to control the virtual sustain pedal,
pedal_type
is ignored and level
is 0 or 1.
To apply such a PFT to a Score
:
Score.vsustain_pft(pft: PFT, t0: float=0, selector:Selector=None)
t0
is the score start time, and selector
specifies which notes are affected
by the virtual pedal.