-
Notifications
You must be signed in to change notification settings - Fork 1
/
waves.py
56 lines (37 loc) · 1.26 KB
/
waves.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import numpy as np
import pandas as pd
from scipy.signal import sawtooth, square
from smoothing import smooth
from adsr import Envelope
FREQUENCY_DATA = pd.read_csv('utils/notesFrequencies')
FREQUENCY_MAP = dict(zip(FREQUENCY_DATA.note, FREQUENCY_DATA.frequency))
class Wave(np.ndarray):
signal = None
def __new__(cls, frequency, duration, samplerate=44100):
if isinstance(frequency, str):
try:
frequency = FREQUENCY_MAP[frequency]
except KeyError:
raise(f'Note should be one of {FREQUENCY_MAP.keys()}')
ts = np.arange(0, duration, 1 / samplerate)
cls._set_signal(2 * np.pi * frequency * ts)
obj = np.asarray(cls.signal, dtype=np.float32).view(cls)
obj.__setattr__('samplerate', samplerate)
obj.__setattr__('duration', duration)
return obj
class SawTooth(Wave):
@classmethod
def _set_signal(cls, x):
cls.signal = sawtooth(x)
class Triangle(Wave):
@classmethod
def _set_signal(cls, x):
cls.signal = 2 * np.abs(sawtooth(x)) - 1
class Square(Wave):
@classmethod
def _set_signal(cls, x):
cls.signal = square(x)
class Sine(Wave):
@classmethod
def _set_signal(cls, x):
cls.signal = np.sin(x)