Skip to content

Commit

Permalink
changes to lectures
Browse files Browse the repository at this point in the history
  • Loading branch information
xserra committed Mar 6, 2014
1 parent 42ac636 commit acbd65f
Show file tree
Hide file tree
Showing 26 changed files with 540 additions and 174 deletions.
2 changes: 1 addition & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Fabià Serra Arrizabalaga
Xavier Serra
Fabià Serra Arrizabalaga
Sankalp Gulati
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sms-tools
=========

<p>Spectral modeling analysis and synthesis tools written in python and C for sound and music applications, plus some complementary material.</p>
<p>Spectral modeling analysis and synthesis tools written in python and C for sound and music applications, plus complementary teaching material.</p>

<p> In order to use all the software you have to install version 2.7 of python and the following modules: iPython, Matplotlib, Numpy, Scipy, PyAudio, PySide, Cython. Some of the code also requires to install the <a href="http://essentia.upf.edu/"> Essentia library</a>. </p>

Expand All @@ -11,9 +11,9 @@ sms-tools

<p>There are examples of analysis/transformation/synthesis in the examples directory. All the sounds used in the examples are in the sounds directory.</p>

<p>In order to use the C functions, which will run most the code faster, you need to compile basicFunctions_C. Once Cython is installed, in the Terminal go to the directory software/utilFunctions_C and write <code> python compileModule.py build_ext --inplace </code> (don't bother if it appears a warning) </p>
<p>In order to use the C functions, which will run most the code faster, you need to compile basicFunctions_C. Once Cython is installed, in the Terminal go to the directory software/utilFunctions_C and write <code> python compileModule.py build_ext --inplace </code> </p>

<p>All this code is used in several classes that I teach. The slides and demo code I use in class is available in the lectures directory.</p>
<p>All this code is used in several classes that I teach. The slides and demo code used in class is available in the lectures directory.</p>



Expand Down
Binary file modified lectures/1-Introduction/Basic-mathematics.odp
Binary file not shown.
Binary file modified lectures/1-Introduction/Intro-to-DSP.odp
Binary file not shown.
Binary file modified lectures/4-STFT/STFT-2.odp
Binary file not shown.
Binary file modified lectures/6-Harmonic-model/Harmonic-model.odp
Binary file not shown.
Binary file not shown.
Binary file modified lectures/7-Sinusoidal-plus-residual-model/Stochastic-model.odp
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions lectures/7-Sinusoidal-plus-residual-model/plots-code/LPC.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hamming, hanning, triang, blackmanharris, resample
import math
import sys, os, time
from scipy.fftpack import fft, ifft
import essentia.standard as ess

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/utilFunctions/'))
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/models/'))
import waveIO as WIO


lpc = ess.LPC(order=14)
N= 512
(fs, x) = WIO.wavread('../../../sounds/soprano-E4.wav')
first = 20000
last = first+N
x1 = x[first:last]
X = fft(hamming(N)*x1)
mX = 20 * np.log10(abs(X[:N/2]))

coeff = lpc(x1)
Y = fft(coeff[0], N)
mY = 20 * np.log10(abs(Y[:N/2]))


plt.figure(1)
plt.subplot(2,1,1)
plt.plot(np.arange(first, last)/float(fs), x[first:last], 'b')
plt.axis([first/float(fs), last/float(fs), min(x[first:last]), max(x[first:last])])
plt.title('x (soprano-E4.wav)')

plt.subplot(2,1,2)
plt.plot(np.arange(0, fs/2.0, fs/float(N)), mX-max(mX), 'r', label="mX")
plt.plot(np.arange(0, fs/2.0, fs/float(N)), -mY-max(-mY)-3, 'k', label="mY")
plt.legend()
plt.axis([0, fs/2, -60, 3])
plt.title('magnitude spectrum and LPC approximation')

plt.show()
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hamming, hanning, triang, blackmanharris, resample
import math
import sys, os, time
from scipy.fftpack import fft, ifft

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/utilFunctions/'))
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/models/'))
import waveIO as WIO
import dftAnal

def stochasticModelFrame(x, w, N, stocf) :
# x: input array sound, w: analysis window, N: FFT size,
# stocf: decimation factor of mag spectrum for stochastic analysis
hN = N/2 # size of positive spectrum
hM = (w.size)/2 # half analysis window size
pin = hM # initialize sound pointer in middle of analysis window
fftbuffer = np.zeros(N) # initialize buffer for FFT
yw = np.zeros(w.size) # initialize output sound frame
w = w / sum(w) # normalize analysis window
#-----analysis-----
xw = x[pin-hM:pin+hM] * w # window the input sound
X = fft(xw) # compute FFT
mX = 20 * np.log10( abs(X[:hN]) ) # magnitude spectrum of positive frequencies
mXenv = resample(np.maximum(-200, mX), mX.size*stocf) # decimate the mag spectrum
pX = np.angle(X[:hN])
#-----synthesis-----
mY = resample(mXenv, hN) # interpolate to original size
pY = 2*np.pi*np.random.rand(hN) # generate phase random values
Y = np.zeros(N, dtype = complex)
Y[:hN] = 10**(mY/20) * np.exp(1j*pY) # generate positive freq.
Y[hN+1:] = 10**(mY[:0:-1]/20) * np.exp(-1j*pY[:0:-1]) # generate negative freq.
fftbuffer = np.real( ifft(Y) ) # inverse FFT
y = fftbuffer*N/2
return mX, pX, mY, pY, y


# example call of stochasticModel function
if __name__ == '__main__':
(fs, x) = WIO.wavread('../../../sounds/ocean.wav')
w = np.hanning(512)
N = 512
stocf = .1
envSize = (N * stocf) // 2
maxFreq = 10000.0
lastbin = N*maxFreq/fs
first = 4000
last = first+w.size
mX, pX = dftAnal.dftAnal(x[first:last], w, N)
mXenv = resample(np.maximum(-200, mX), envSize)
mY = resample(mXenv, N/2)
plt.figure(1)
plt.plot(float(fs)*np.arange(0, N/2)/N, mX, 'r', label=r'$a$')
plt.plot(float(fs/2.0)*np.arange(0, envSize)/envSize, mXenv, color='k', label=r'$\tilde a$')
plt.plot(float(fs)*np.arange(0, N/2)/N, mY, 'g', label=r'$b$')
plt.legend()
plt.axis([0, maxFreq, -80, max(mX)+3])
plt.title('envelope approximation')
plt.show()
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hamming, hanning, resample
from scipy.fftpack import fft, ifft
import time
import sys, os

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/utilFunctions/'))
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/models/'))

import waveIO as WIO
import stochasticModelAnal, stochasticModel,stftAnal

(fs, x) = WIO.wavread('../../../sounds/ocean.wav')
w = np.hamming(512)
N = 512
H = 256
stocf = .1
mXenv = stochasticModelAnal.stochasticModelAnal(x, w, N, H, stocf)
y = stochasticModel.stochasticModel(x, w, N, H, stocf)
mX, pX = stftAnal.stftAnal(x, fs, w, N, H)


plt.figure(1)
plt.subplot(411)
plt.plot(np.arange(x.size)/float(fs), x,'b')
plt.title('input sound x=wavread(ocean.wav)')
plt.axis([0,x.size/float(fs),min(x),max(x)])

plt.subplot(412)
numFrames = int(mX[:,0].size)
frmTime = H*np.arange(numFrames)/float(fs)
binFreq = np.arange(N/2)*float(fs)/N
plt.pcolormesh(frmTime, binFreq, np.transpose(mX))
plt.title('magnitude spectrogram; M=512, N=512, H=256')
plt.autoscale(tight=True)

plt.subplot(413)
numFrames = int(mXenv[:,0].size)
frmTime = H*np.arange(numFrames)/float(fs)
binFreq = np.arange(stocf*N/2)*float(fs)/(stocf*N)
plt.pcolormesh(frmTime, binFreq, np.transpose(mXenv))
plt.title('stochastic approximation; stocf=.1')
plt.autoscale(tight=True)

plt.subplot(414)
plt.plot(np.arange(x.size)/float(fs), y,'b')
plt.title('y')
plt.axis([0,y.size/float(fs),min(y),max(y)])
plt.show()
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,38 +1,23 @@
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hamming, hanning, resample
from scipy.signal import hamming, hanning, triang, blackmanharris, resample
import math
import sys, os, time
from scipy.fftpack import fft, ifft
import time

import sys, os
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/utilFunctions/'))
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/models/'))
import waveIO as WIO

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../../code/basicFunctions/'))
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../../code/basicFunctions_C/'))

import smsWavplayer as wp

try:
import basicFunctions_C as GS
except ImportError:
import smsGenSpecSines as GS
print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
print "NOTE: Cython modules for some functions were not imported, the processing will be slow"
print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"


def stochasticModel(x, w, N, stocf) :
def stochasticModelFrame(x, w, N, stocf) :
# x: input array sound, w: analysis window, N: FFT size,
# stocf: decimation factor of mag spectrum for stochastic analysis
# y: output sound

hN = N/2 # size of positive spectrum
hM = (w.size)/2 # half analysis window size
pin = hM # initialize sound pointer in middle of analysis window
fftbuffer = np.zeros(N) # initialize buffer for FFT
yw = np.zeros(w.size) # initialize output sound frame
w = w / sum(w) # normalize analysis window
ws = hanning(w.size)*2 # synthesis window

#-----analysis-----
xw = x[pin-hM:pin+hM] * w # window the input sound
X = fft(xw) # compute FFT
Expand All @@ -41,46 +26,46 @@ def stochasticModel(x, w, N, stocf) :
pX = np.angle(X[:hN])
#-----synthesis-----
mY = resample(mXenv, hN) # interpolate to original size
pY = 2*np.pi*np.random.rand(hN) # generate phase random values
pY = 2*np.pi*np.random.rand(hN) # generate phase random values
Y = np.zeros(N, dtype = complex)
Y[:hN] = 10**(mY/20) * np.exp(1j*pY) # generate positive freq.
Y[hN+1:] = 10**(mY[:0:-1]/20) * np.exp(-1j*pY[:0:-1]) # generate negative freq.

fftbuffer = np.real( ifft(Y) ) # inverse FFT
y = ws*fftbuffer*N/2 # overlap-add

y = fftbuffer*N/2
return mX, pX, mY, pY, y


# example call of stochasticModel function
if __name__ == '__main__':
(fs, x) = wp.wavread('../../../../sounds/ocean.wav')
(fs, x) = WIO.wavread('../../../sounds/ocean.wav')
w = np.hanning(1024)
N = 1024
stocf = 0.2
maxFreq = 10000.0
lastbin = N*maxFreq/fs
first = 1000
last = first+w.size
mX, pX, mY, pY, y = stochasticModel(x[first:last], w, N, stocf)
mX, pX, mY, pY, y = stochasticModelFrame(x[first:last], w, N, stocf)

plt.figure(1)
plt.subplot(4,1,1)
plt.plot(np.arange(first, last)/float(fs), x[first:last]*w)
plt.axis([first/float(fs), last/float(fs), min(x[first:last]*w), max(x[first:last]*w)])
plt.title('xw')
plt.plot(np.arange(first, last)/float(fs), x[first:last])
plt.axis([first/float(fs), last/float(fs), min(x[first:last]), max(x[first:last])])
plt.title('x (ocean.wav)')
plt.subplot(4,1,2)
plt.plot(np.arange(0, fs/2.0, fs/float(N)), mX, 'b')
plt.plot(np.arange(0, fs/2.0, fs/float(N)), mY, 'r')
plt.plot(np.arange(0, fs/2.0, fs/float(N)), mX, 'r', label="mX")
plt.plot(np.arange(0, fs/2.0, fs/float(N)), mY, 'k', label="mY")
plt.legend()
plt.axis([0, maxFreq, -80, max(mX)+3])
plt.title('mX (blue), mY (red)')
plt.title('magnitude spectrum and approximation')
plt.subplot(4,1,3)
plt.plot(np.arange(0, fs/2.0, fs/float(N)), pX, 'b')
plt.plot(np.arange(0, fs/2.0, fs/float(N)), pY-np.pi, 'r')
plt.plot(np.arange(0, fs/2.0, fs/float(N)), pX, 'c', label="pX")
plt.plot(np.arange(0, fs/2.0, fs/float(N)), pY-np.pi, 'k', label="pY")
plt.axis([0, maxFreq, -np.pi, np.pi])
plt.title('pX (blue), pY (red)')
plt.legend()
plt.title('phase spectrum and random')
plt.subplot(4,1,4)
plt.plot(np.arange(first, last)/float(fs), y)
plt.plot(np.arange(first, last)/float(fs), y, 'b')
plt.axis([first/float(fs), last/float(fs), min(y), max(y)])
plt.title('yw')
plt.title('y')
plt.show()
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,38 +1,23 @@
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hamming, hanning, resample
from scipy.signal import hamming, hanning, triang, blackmanharris, resample
import math
import sys, os, time
from scipy.fftpack import fft, ifft
import time

import sys, os
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/utilFunctions/'))
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../software/models/'))
import waveIO as WIO

sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../../code/basicFunctions/'))
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../../../code/basicFunctions_C/'))

import smsWavplayer as wp

try:
import basicFunctions_C as GS
except ImportError:
import smsGenSpecSines as GS
print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
print "NOTE: Cython modules for some functions were not imported, the processing will be slow"
print "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"


def stochasticModel(x, w, N, stocf) :
def stochasticModelFrame(x, w, N, stocf) :
# x: input array sound, w: analysis window, N: FFT size,
# stocf: decimation factor of mag spectrum for stochastic analysis
# y: output sound

hN = N/2 # size of positive spectrum
hM = (w.size)/2 # half analysis window size
pin = hM # initialize sound pointer in middle of analysis window
fftbuffer = np.zeros(N) # initialize buffer for FFT
yw = np.zeros(w.size) # initialize output sound frame
w = w / sum(w) # normalize analysis window
ws = hanning(w.size)*2 # synthesis window

#-----analysis-----
xw = x[pin-hM:pin+hM] * w # window the input sound
X = fft(xw) # compute FFT
Expand All @@ -41,40 +26,38 @@ def stochasticModel(x, w, N, stocf) :
pX = np.angle(X[:hN])
#-----synthesis-----
mY = resample(mXenv, hN) # interpolate to original size
pY = 2*np.pi*np.random.rand(hN) # generate phase random values
pY = 2*np.pi*np.random.rand(hN) # generate phase random values
Y = np.zeros(N, dtype = complex)
Y[:hN] = 10**(mY/20) * np.exp(1j*pY) # generate positive freq.
Y[hN+1:] = 10**(mY[:0:-1]/20) * np.exp(-1j*pY[:0:-1]) # generate negative freq.

fftbuffer = np.real( ifft(Y) ) # inverse FFT
y = ws*fftbuffer*N/2 # overlap-add

y = fftbuffer*N/2
return mX, pX, mY, pY, y


# example call of stochasticModel function
if __name__ == '__main__':
(fs, x) = wp.wavread('../../../../sounds/ocean.wav')
(fs, x) = WIO.wavread('../../../sounds/ocean.wav')
w = np.hanning(1024)
N = 1024
stocf = 0.1
maxFreq = 10000.0
lastbin = N*maxFreq/fs
first = 1000
last = first+w.size
mX, pX, mY, pY, y = stochasticModel(x[first:last], w, N, stocf)
mX, pX, mY, pY, y = stochasticModelFrame(x[first:last], w, N, stocf)

plt.figure(1)
plt.subplot(3,1,1)
plt.plot(np.arange(0, fs/2.0, fs/float(N)), mY, 'b')
plt.plot(np.arange(0, fs/2.0, fs/float(N)), mY, 'r', label="mY")
plt.axis([0, maxFreq, -80, max(mX)+3])
plt.title('mY')
plt.title('magnitude spectrum (approx of mX)')
plt.subplot(3,1,2)
plt.plot(np.arange(0, fs/2.0, fs/float(N)), pY-np.pi, 'b')
plt.plot(np.arange(0, fs/2.0, fs/float(N)), pY-np.pi, 'c', label="pY")
plt.axis([0, maxFreq, -np.pi, np.pi])
plt.title('pY')
plt.title('phase spectrum (random)')
plt.subplot(3,1,3)
plt.plot(np.arange(first, last)/float(fs), y)
plt.plot(np.arange(first, last)/float(fs), y, 'b')
plt.axis([first/float(fs), last/float(fs), min(y), max(y)])
plt.title('yw')
plt.title('y')
plt.show()
Loading

0 comments on commit acbd65f

Please sign in to comment.