karplus-strong in python
parent
7fa52a235a
commit
181393821a
@ -0,0 +1,54 @@
|
||||
############################################################
|
||||
#
|
||||
# karplus-simple.py
|
||||
#
|
||||
# Author: MV (http://electro-nut.blogspot.com/)
|
||||
#
|
||||
# Generates a plucked string sound WAV file using the
|
||||
# Karplus-Strong algorithm. (Simple version.)
|
||||
#
|
||||
############################################################
|
||||
from math import sin, pi
|
||||
from array import array
|
||||
from random import random
|
||||
|
||||
import wave
|
||||
|
||||
# KS params
|
||||
SR = 44100
|
||||
f = 220
|
||||
N = SR/f
|
||||
|
||||
# WAV params
|
||||
NCHANNELS = 1
|
||||
SWIDTH = 2
|
||||
FRAME_RATE = 44100
|
||||
NFRAMES = 44100
|
||||
NSAMPLES = 44100
|
||||
# max - 128 for 8-bit, 32767 for 16-bit
|
||||
MAX_VAL= 32767
|
||||
|
||||
# pluck
|
||||
buf = [random() - 0.5 for i in range(N)]
|
||||
|
||||
#init samples
|
||||
samples = []
|
||||
|
||||
# KS - ring buffer
|
||||
bufSize = len(buf)
|
||||
for i in range(NSAMPLES):
|
||||
samples.append(buf[0])
|
||||
avg = 0.996*0.5*(buf[0] + buf[1])
|
||||
buf.append(avg)
|
||||
buf.pop(0)
|
||||
|
||||
# samples to 16-bit to string
|
||||
tmpBuf = [int(x*MAX_VAL) for x in samples]
|
||||
data = array('h', tmpBuf).tostring()
|
||||
|
||||
# write out WAV file
|
||||
file = wave.open('karplus-simple.wav', 'wb')
|
||||
file.setparams((NCHANNELS, SWIDTH, FRAME_RATE, NFRAMES,
|
||||
'NONE', 'noncompressed'))
|
||||
file.writeframes(data)
|
||||
file.close()
|
Binary file not shown.
@ -0,0 +1,66 @@
|
||||
############################################################
|
||||
#
|
||||
# karplus.py
|
||||
#
|
||||
# Author: MV (http://electro-nut.blogspot.com/)
|
||||
#
|
||||
# Generates a plucked string sound WAV file using the
|
||||
# Karplus-Strong algorithm.
|
||||
#
|
||||
############################################################
|
||||
from math import sin, pi
|
||||
from array import array
|
||||
from random import random
|
||||
import wave
|
||||
|
||||
# KS params
|
||||
SR = 44100
|
||||
f = 220
|
||||
|
||||
# WAV params
|
||||
NCHANNELS = 1
|
||||
SWIDTH = 2
|
||||
FRAME_RATE = 44100
|
||||
NFRAMES = 44100
|
||||
NSAMPLES = 44100*2
|
||||
# max - 128 for 8-bit, 32767 for 16-bit
|
||||
MAX_VAL= 32767
|
||||
|
||||
class String:
|
||||
def __init__(self, freq, SR):
|
||||
self.freq = freq
|
||||
self.N = SR/freq
|
||||
# 'pluck' string
|
||||
def pluck(self):
|
||||
self.buf = [random() - 0.5 for i in range(self.N)]
|
||||
# return current sample, increment step
|
||||
def sample(self):
|
||||
val = self.buf[0]
|
||||
avg = 0.996*0.5*(self.buf[0] + self.buf[1])
|
||||
self.buf.append(avg)
|
||||
self.buf.pop(0)
|
||||
return val
|
||||
|
||||
str1, str2 = String(196, SR), String(440, SR)
|
||||
|
||||
str1.pluck()
|
||||
str2.pluck()
|
||||
|
||||
samples = []
|
||||
|
||||
for i in range(NSAMPLES):
|
||||
sample = str1.sample()
|
||||
if(i > NSAMPLES/8):
|
||||
sample += str2.sample()
|
||||
samples.append(sample)
|
||||
|
||||
# samples to 16-bit to string
|
||||
tmpBuf = [int(x*MAX_VAL) for x in samples]
|
||||
data = array('h', tmpBuf).tostring()
|
||||
|
||||
# write out WAV file
|
||||
file = wave.open('karplus.wav', 'wb')
|
||||
file.setparams((NCHANNELS, SWIDTH, FRAME_RATE, NFRAMES,
|
||||
'NONE', 'noncompressed'))
|
||||
file.writeframes(data)
|
||||
file.close()
|
Binary file not shown.
Reference in New Issue