Add decay to synthetiser

This commit is contained in:
Bartłomiej Pluta
2019-07-29 21:43:20 +02:00
parent 07f08b0557
commit 8abae7c2ff
2 changed files with 51 additions and 19 deletions

View File

@@ -12,14 +12,14 @@ def pause(value, bpm):
time.sleep(60 * 4 / value / bpm)
def play(notes, bpm, overtones):
compiled = compilePolyphony(notes, bpm, overtones)
def play(notes, config):
compiled = compilePolyphony(notes, config)
sd.play(compiled)
time.sleep(len(compiled) / FS)
def compilePolyphony(notes, bpm, overtones):
compiledLines = [1 / len(notes) * compileNotes(line, bpm, overtones) for line in notes]
def compilePolyphony(notes, config):
compiledLines = [1 / len(notes) * compileNotes(line, config) for line in notes]
return sum(adjustSize(compiledLines))
@@ -29,30 +29,36 @@ def adjustSize(compiledLines):
return [np.concatenate([line, np.zeros(maxSize - len(line))]) for line in compiledLines]
def compileNotes(notes, bpm, overtones):
def compileNotes(notes, config):
dispatcher = {
Type.NOTE: lambda note, overtones: sineForNote(note.value, bpm, overtones),
Type.INTEGER: lambda note, overtones: silenceForPause(note.value, bpm)
Type.NOTE: lambda note, overtones: sineForNote(note.value, config),
Type.INTEGER: lambda note, overtones: silenceForPause(note.value, config)
}
return np.concatenate([dispatcher[note.type](note, overtones) for note in notes])
return np.concatenate([dispatcher[note.type](note, config) for note in notes])
def sineForNote(note, bpm, overtones):
def sineForNote(note, config):
frequency = note.toFrequency()
duration = 60 * 4 / note.duration / bpm
duration = 60 * 4 / note.duration / config.bpm
duration *= 1.5 if note.dot else 1
return sound(frequency, duration, overtones)
return sound(frequency, duration, config)
def sound(frequency, duration, overtones):
return sum(a * sine((i+1) * frequency, duration) for i, a in enumerate(overtones))
def sound(frequency, duration, config):
return decay(sum(a * sine((i+1) * frequency, duration) for i, a in enumerate(config.overtones)), config)
def decay(wave, config):
magnitude = np.exp(-config.decay/len(wave) * np.arange(len(wave)))
return magnitude * wave
def sine(frequency, duration):
return (np.sin(2 * np.pi * np.arange(FS * duration) * frequency / FS)).astype(np.float32)
def silenceForPause(value, bpm):
duration = 60 * 4 / value / bpm
def silenceForPause(value, config):
duration = 60 * 4 / value / config.bpm
return np.zeros(int(FS * duration))