-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkarplus.py
141 lines (76 loc) · 3.03 KB
/
karplus.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import time, random
import argparse
import math
import wave
import random
import argparse
import os, sys
import pygame
from collections import deque
import numpy as np
import matplotlib.pyplot as plt
gShowPlot = False
pmNotes = {'C4':262, 'Eb':311, 'F':349, 'G':391, 'Bb':466}
class NotePlayer:
def __init__(self):
pygame.mixer.pre_init( 44100, -16, 1, 2048)
pygame.init()
self.notes = {}
def add(self, fileName):
self.notes[fileName] = pygame.mixer.Sound(fileName)
def play(self, fileName):
try:
self.notes[fileName].play()
except:
print(fileName + ' not found !')
def playRandom(self):
index = random.randint(0, len(self.notes)-1)
note = list(self.notes.values())[index]
note.play()
def generateNote(freq):
nSamples = 44100
sampleRate = 44100
N = int(sampleRate/freq)
buf = deque([random.random() - 0.5 for i in range(N)])
# buf = deque([random.random() - 0.5 for i in range(N)], N)
samples = np.array([0]*nSamples, 'float32')
for i in range(nSamples):
samples[i] = buf[0]
avg = 0.996 * 0.5 * (buf[0] + buf[1])
buf.append(avg)
buf.popleft()
samples = np.array(samples*32767, 'int16')
return samples.tostring()
def writeWave(fname, data):
with wave.open(fname, 'wb') as file:
nChannels = 1
sampleWidth = 2
frameRate = 44100
nFrames = 44100
file.setparams((nChannels, sampleWidth, frameRate, nFrames,
'NONE', 'noncompressed'))
file.writeframes(data)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='''Fenerating sounds with
Karplus String Algorithm''')
parser.add_argument('--display', action='store_true', required=False)
parser.add_argument('--play', action='store_true', required=False)
parser.add_argument('--piano', action='store_true', required=False)
args = parser.parse_args()
if args.display:
gShowPlot = True
plt.ion()
nplayer = NotePlayer()
print('creating notes...')
for name, freq in list(pmNotes.items()):
fileName = name + '.wav'
if not os.path.exists(fileName) or args.display:
data = generateNote(freq)
print('creating ' + fileName + '...')
writeWave(fileName, data)
else:
print('fileName already created. dkipping ...')
nplayer.add(name + '.wav')
if args.display:
nplayer.play(name + 'wav')
time.sleep(0.5)