) and self.sustain >= 0 and self.sustain <= 1
assert isinstance(self.release, int) and self.release >= 0
- class State(Enum):
- OFF = auto()
- ATTACK = auto()
- DECAY = auto()
- SUSTAIN = auto()
- RELEASE = auto()
-
def __init__(self, envelope):
self.envelope = envelope
self.prev_signal = False
- self.pos = 0
+ self.state = 0
self.velocity = 0
- self.state = self.State.OFF
+ self.pos = 0
def __call__(self, signal):
+ # signal to no signal -> release
if self.prev_signal and not signal:
- self.velocity = -self.pos / self.envelope.release
- self.state = self.State.RELEASE
+ self.state = 3
+ self.velocity = -self.envelope.sustain / self.envelope.release
+ # no signal or release to signal -> attack
elif signal and not self.prev_signal:
- self.velocity = (1 - self.pos) / self.envelope.attack
- self.state = self.State.ATTACK
+ self.state = 1
+ self.velocity = 1 / self.envelope.attack
self.pos += self.velocity
# attack -> decay
- if self.state == self.State.ATTACK and self.pos >= 1:
- self.pos = 1
- self.velocity = (self.envelope.sustain - 1) / self.envelope.decay
- self.state = self.State.DECAY
+ if self.state == 1 and self.pos >= 1:
+ self.state = 2
+ self.velocity = -(1 - self.envelope.sustain) / self.envelope.decay
# decay -> sustain
- elif (
- self.state == self.State.DECAY
- and self.pos <= self.envelope.sustain
- ):
- self.pos = self.envelope.sustain
+ elif self.state == 2 and self.pos <= self.envelope.sustain:
self.velocity = 0
- self.state = self.State.SUSTAIN if self.pos > 0 else self.State.OFF
# release -> off
- elif self.state == self.State.RELEASE and self.pos <= 0:
- self.pos = self.velocity = 0
- self.state = self.State.OFF
+ elif self.state == 3 and self.pos <= 0:
+ self.state = self.velocity = self.pos = 0
self.prev_signal = signal
return self.pos
def has_signal(self):
- return self.state != self.State.OFF
+ return self.state != 0
self.surf.fill("darkgray")
self.piano_keys.draw(self.surf)
self.key_vis.draw(self.surf)
- fs, r = self.font.render(str(len(self.channel_manager.tones)), "black")
- self.surf.blit(fs, (self.surf.get_width() - r.width - 30, 30))
pygame.display.update()
def update(self):