Add polyphony AND add overtones do synthesed tones
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
from smnp.function.model import Function
|
||||
from smnp.function.signature import signature
|
||||
from smnp.module.synth.lib import player
|
||||
from smnp.module.synth.lib.wave import pause
|
||||
from smnp.type.model import Type
|
||||
from smnp.type.signature.matcher.type import ofTypes
|
||||
|
||||
_signature = signature(ofTypes(Type.INTEGER))
|
||||
def _function(env, value):
|
||||
bpm = env.findVariable('bpm')
|
||||
player.pause(value.value, bpm.value)
|
||||
pause(value.value, bpm.value)
|
||||
|
||||
|
||||
function = Function(_signature, _function, 'pause')
|
||||
@@ -1,13 +1,24 @@
|
||||
from smnp.function.model import Function
|
||||
from smnp.function.signature import signature
|
||||
from smnp.module.synth.lib.player import play
|
||||
from smnp.function.model import Function, CombinedFunction
|
||||
from smnp.function.signature import varargSignature
|
||||
from smnp.module.synth.lib.wave import play
|
||||
|
||||
from smnp.type.model import Type
|
||||
from smnp.type.signature.matcher.type import ofType
|
||||
from smnp.type.signature.matcher.list import listOf
|
||||
from smnp.type.signature.matcher.type import ofTypes
|
||||
|
||||
_signature = signature(ofType(Type.NOTE))
|
||||
def _function(env, note):
|
||||
bpm = env.findVariable('bpm')
|
||||
play(note.value, bpm.value)
|
||||
_signature1 = varargSignature(listOf(Type.NOTE, Type.INTEGER))
|
||||
def _function1(env, notes):
|
||||
rawNotes = [note.value for note in notes]
|
||||
play(rawNotes, env.findVariable("bpm").value, env.findVariable("overtones").value)
|
||||
|
||||
|
||||
function = Function(_signature, _function, 'synthNote')
|
||||
_signature2 = varargSignature(ofTypes(Type.NOTE, Type.INTEGER))
|
||||
def _function2(env, notes):
|
||||
play([ notes ], env.findVariable("bpm").value, env.findVariable("overtones").value)
|
||||
|
||||
|
||||
function = CombinedFunction(
|
||||
'synth',
|
||||
Function(_signature1, _function1),
|
||||
Function(_signature2, _function2)
|
||||
)
|
||||
@@ -1,24 +0,0 @@
|
||||
import time
|
||||
|
||||
from smnp.module.synth.lib.wave import sine
|
||||
from smnp.note.model import Note
|
||||
|
||||
|
||||
def playNotes(notes, bpm):
|
||||
for note in notes:
|
||||
{
|
||||
Note: play,
|
||||
int: pause
|
||||
}[type(note)](note, bpm)
|
||||
|
||||
|
||||
def play(note, bpm):
|
||||
frequency = note.toFrequency()
|
||||
duration = 60 * 4 / note.duration / bpm
|
||||
duration *= 1.5 if note.dot else 1
|
||||
sine(frequency, duration)
|
||||
|
||||
|
||||
def pause(value, bpm):
|
||||
time.sleep(60 * 4 / value / bpm)
|
||||
|
||||
@@ -3,10 +3,56 @@ import time
|
||||
import numpy as np
|
||||
import sounddevice as sd
|
||||
|
||||
from smnp.type.model import Type
|
||||
|
||||
FS = 44100
|
||||
|
||||
|
||||
def pause(value, bpm):
|
||||
time.sleep(60 * 4 / value / bpm)
|
||||
|
||||
|
||||
def play(notes, bpm, overtones):
|
||||
compiled = compilePolyphony(notes, bpm, overtones)
|
||||
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]
|
||||
return sum(adjustSize(compiledLines))
|
||||
|
||||
|
||||
def adjustSize(compiledLines):
|
||||
maxSize = max(len(line) for line in compiledLines)
|
||||
|
||||
return [np.concatenate([line, np.zeros(maxSize - len(line))]) for line in compiledLines]
|
||||
|
||||
|
||||
def compileNotes(notes, bpm, overtones):
|
||||
dispatcher = {
|
||||
Type.NOTE: lambda note, overtones: sineForNote(note.value, bpm, overtones),
|
||||
Type.INTEGER: lambda note, overtones: silenceForPause(note.value, bpm)
|
||||
}
|
||||
|
||||
return np.concatenate([dispatcher[note.type](note, overtones) for note in notes])
|
||||
|
||||
|
||||
def sineForNote(note, bpm, overtones):
|
||||
frequency = note.toFrequency()
|
||||
duration = 60 * 4 / note.duration / bpm
|
||||
duration *= 1.5 if note.dot else 1
|
||||
return sound(frequency, duration, overtones)
|
||||
|
||||
|
||||
def sound(frequency, duration, overtones):
|
||||
return sum(a.value * sine((i+1) * frequency, duration) for i, a in enumerate(overtones))
|
||||
|
||||
|
||||
def sine(frequency, duration):
|
||||
samples = (np.sin(2*np.pi*np.arange(FS*duration)*frequency/FS)).astype(np.float32)
|
||||
sd.play(samples, FS)
|
||||
time.sleep(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
|
||||
return np.zeros(int(FS * duration))
|
||||
|
||||
Reference in New Issue
Block a user