Physical Modeling: Karplus Strong - Implementation

plucked_string_444.png


import numpy as np
from   numpy import linspace, sin, zeros
from   math import pi
%matplotlib notebook
import matplotlib.pyplot as plt
from   tikzplotlib import save as tikz_save

from   IPython.display import display, Markdown, clear_output
import IPython.display as ipd
import ipywidgets as widgets
from   ipywidgets import *




fs          = 48000
L           = 500



# a function for appending the array again and again
# arbitrary 300 times ...
def appender(x):
    y = np.array([])

    for i in range(300):
        y = np.append(y,x*0.33)

    return y


x = np.random.standard_normal(L)
y = appender(x)

t = np.linspace(0,len(y)/fs,len(y))
f = np.linspace(0,1,len(y))

fig   = plt.figure()
ax    = fig.add_subplot(2, 1, 1)
line, = ax.plot(t,y)

ax2    = fig.add_subplot(2, 1, 2)
Y = abs(np.fft.fft(y))

Y = Y[0:5000]
f = f[0:5000]

line2, = ax2.plot(f,Y)

def update(L = widgets.IntSlider(min = 10, max= 1500, step=1, value=500)):

    x = np.random.standard_normal(L)
    y = appender(x)

    t = np.linspace(0,len(y)/fs,len(y))
    f = np.linspace(0,1,len(y))

    Y = abs(np.fft.fft(y))
    Y = Y[0:5000]
    f = f[0:5000]

    line.set_ydata(y)
    line2.set_ydata(Y)

    fig.canvas.draw_idle()
    ipd.display(ipd.Audio(y, rate=fs))



interact(update);
<IPython.core.display.Javascript object>
interactive(children=(IntSlider(value=500, description='L', max=1500, min=10), Output()), _dom_classes=('widge…

Karplus-Strong

Karplus-Strong makes use of the random buffer.

# this implementation serves for a better
# understanding and is not efficient
#
# - wait for process to be finished in
#   interactive use


fs          = 48000
L           = 500

# the feedback gain
gain   = 0.99

# the number of samples used for smoothing
smooth = 10


def karplus_strong(L,gain,smooth):

    x = np.random.standard_normal(L)
    y = np.array([])


    for i in range(96000):
        k   = i%L
        tmp = 0;

        for j in range(smooth):
            tmp += x[(k+j) %L]

        tmp = tmp/smooth

        x[k] = gain*tmp
        y = np.append(y,tmp)

    return y


y = karplus_strong(L,gain,smooth)

t = np.linspace(0,len(y)/fs,len(y))
f = np.linspace(0,1,len(y))

fig   = plt.figure()
ax    = fig.add_subplot(2, 1, 1)
line, = ax.plot(t,y)

ax2    = fig.add_subplot(2, 1, 2)
Y = abs(np.fft.fft(y))

Y = Y[0:5000]
f = f[0:5000]

line2, = ax2.plot(f,Y)

def update(b = widgets.ToggleButtons( options=['Recalculate','Recalculate'],disabled=False),
          L = widgets.IntSlider(min = 10, max= 1500, step=1, value=500),
           gain = widgets.FloatSlider(min = 0.8, max= 1, step=0.01, value=0.99),
          smooth = widgets.IntSlider(min = 1, max= 20, step=1, value=10)):

    print(b)
    y = karplus_strong(L,gain,smooth)

    t = np.linspace(0,len(y)/fs,len(y))
    f = np.linspace(0,1,len(y))

    Y = abs(np.fft.fft(y))
    Y = Y[0:5000]
    f = f[0:5000]

    line.set_ydata(y)
    line2.set_ydata(Y)

    fig.canvas.draw_idle()
    ipd.display(ipd.Audio(y, rate=fs))



interact(update);
<IPython.core.display.Javascript object>
interactive(children=(ToggleButtons(description='b', options=('Recalculate', 'Recalculate'), value='Recalculat…

References

  • Vesa Välimäki. Discrete-time modeling of acoustic tubes using fractional delay filters. Helsinki University of Technology, 1995.
    [BibTeX▼]
  • Gijs de Bruin and Maarten van Walstijn. Physical models of wind instruments: A generalized excitation coupled with a modular tube simulation platform*. Journal of New Music Research, 24(2):148–163, 1995.
    [BibTeX▼]
  • Matti Karjalainen, Vesa Välimäki, and Zoltán Jánosy. Towards High-Quality Sound Synthesis of the Guitar and String Instruments. In Computer Music Association, 56–63. 1993.
    [BibTeX▼]
  • Julius O Smith. Physical modeling using digital waveguides. Computer music journal, 16(4):74–91, 1992.
    [BibTeX▼]
  • Lejaren Hiller and Pierre Ruiz. Synthesizing musical sounds by solving the wave equation for vibrating objects: part 1. Journal of the Audio Engineering Society, 19(6):462–470, 1971.
    [BibTeX▼]
  • Lejaren Hiller and Pierre Ruiz. Synthesizing musical sounds by solving the wave equation for vibrating objects: part 2. Journal of the Audio Engineering Society, 19(7):542–551, 1971.
    [BibTeX▼]


  • Contents © Henrik von Coler 2020 - Contact