Discrete Signals


By Prof. Seungchul Lee
http://iai.postech.ac.kr/
Industrial AI Lab at POSTECH

1. Discrete Time Signals

A signal x[n] is a function that maps an independent variable to a dependent variable.

In this course, we will focus on discrete-time signals x[n]:

  • Independent variable is an integer: nZ
  • Dependent variable is a real or complex number: x[n]R or C




1.1. Plot Real Signals

  • plot for continuous signals in Python

  • stem for discrete signals in Python

x(t)=sin(2πt)
In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
In [2]:
t = np.linspace(0,2,200)
x = np.sin(2*np.pi*t)

# plot
plt.figure(figsize = (10,4))
plt.plot(t, x)
plt.xlim([np.min(t), np.max(t)])
plt.xlabel('t [sec]')
plt.ylabel('x(t)')
plt.show()
x[n]=sin(2πNn)
In [3]:
N = 20
n = np.arange(0, N)
x = np.sin(2*np.pi/N*n)

# plot
plt.figure(figsize = (10, 8))
plt.subplot(2,1,1)
plt.plot(n, x, 'o')
plt.xlim([np.min(n), np.max(n)])
plt.title('plot')

plt.subplot(2,1,2)
plt.stem(n, x)
plt.xlim([np.min(n), np.max(n)])
plt.title('stem')
plt.show()

1.2. Signal Sounds

In [ ]:
from google.colab import drive
drive.mount('/content/drive')
In [4]:
from scipy.io import wavfile
from IPython.display import Audio

fs, data = wavfile.read('/content/drive/MyDrive/Colab Notebooks/data_files/hamlet.wav')
In [5]:
# signal: 'ALas, Poor Yorick!'

plt.figure(figsize = (10, 4))
plt.plot(data)
plt.show()
In [6]:
Audio('/content/drive/MyDrive/Colab Notebooks/data_files//hamlet.wav')
Out[6]:
x[n]=cos(2πNkn)
In [7]:
# cosine wave

N = 44100
n = np.arange(0, 2*N)
k = 40 # frequancy
coswave = np.cos(2*np.pi/N*k*n)

# plot
plt.figure(figsize = (10, 4))
plt.plot(n/fs, coswave)
plt.show()
In [8]:
Audio(coswave, rate = fs)
Out[8]:

Chirp

x[n]=0.3cos(2π3000000n2)
In [9]:
# chirp (https://en.wikipedia.org/wiki/Chirp)
n = np.arange(0,44100*2)
chirp = 0.3*np.cos(2*np.pi/3000000*n**2)

# plot
plt.figure(figsize = (10, 4))
plt.plot(n/fs, chirp)
plt.xlim([0, 0.4])
plt.show()
In [10]:
Audio(chirp, rate = 44100)
Out[10]:

White noise

In [11]:
# white gaussian noise
N = 44100
noise = 0.1*np.random.randn(2*N,1)

# plot
plt.figure(figsize = (10, 4))
plt.plot(n/fs, noise)
plt.xlim([0, 0.4])
plt.show()
In [12]:
Audio(noise.T, rate = fs) 
Out[12]:

2. Complex Sinusoid

2.1. Complex Numbers

z1=a1+b1i,z1=[a1b1]


z2=a2+b2i,z2=[a2b2]

  • Addition
z=z1+z2=(a1+a2)+(b1+b2)iz=z1+z2=[a1b1]+[a2b2]=[a1+a2b1+b2]




  • Multiplication
{z1=r1eiθ1z2=r2eiθ2{z1z2=r1r2ei(θ1+θ2)z1z2=r1r2ei(θ1θ2)



  • Euler's Formula:
eiθ=cosθ+isinθ
  • Complex number in complex exponential
z=rcosθ+irsinθ=r(cosθ+isinθ)=reiθr:magnitude (length)θ:phase (angle)




  • When x[n]C, we can use two signal plots


x[n]=Re{x[n]}+jIm{x[n]}Rectangular formx[n]=|x[n]|ejx[n]Polar form


  • For ejωt




2.2. Geometrical Meaning of eiθ

  • eiθ:point on the unit circle with angle of θ



  • θ=ωt
  • eiωt:rotating on an unit circle with angular velocity of ω.



  • Question: what is the physical meaning of eiωt?
  • Frequency ω determines rotation speed and direction of a circular motion
    • ω>0 counterclockwise rotation
    • ω<0 clockwise rotation

2.3. Sinusoidal Functions from Circular Motions



  • A complex sinusoid is a helix
    • Real part (cos term) is the projection onto the Re axis.
    • Imaginary part (sin term) is the projection onto the Im axis.



cosωt=eiωt+eiωt2

3. Discrete Sinusoids

Discrete Sinusoids


x[n]=Acos(ω0n+ϕ)orx[n]=Aej(ω0n+ϕ)whereω0=2πNk


Key question: which one is a higher frequency?

ω0=π   or   ω0=3π2
In [13]:
n = np.arange(0, 8) # 0,1,2,3 ~ 7
x1 = np.cos(np.pi*n)
x2 = np.cos(3/2*np.pi*n)

# plot
plt.figure(figsize = (10, 8))
plt.subplot(2,1,1)
plt.stem(n, x1)
plt.ylim([-1.5, 1.5])
plt.title('$x_1$')

plt.subplot(2,1,2)
plt.stem(n, x2)
plt.ylim([-1.5, 1.5])
plt.title('$x_2$')
plt.xlabel('n')
plt.show()
In [14]:
n = np.arange(0, 8)
x1 = np.cos(np.pi*n)
x2 = np.cos(3/2*np.pi*n)

n_real = np.linspace(0,7,200)
x1_real = np.cos(np.pi*n_real)
x2_real = np.cos(3/2*np.pi*n_real)

# plot
plt.figure(figsize = (10, 8))
plt.subplot(2,1,1)
plt.stem(n, x1, markerfmt='ro')
plt.plot(n_real,x1_real,'--')
plt.ylim([-1.5, 1.5])
plt.title('$x_1$')

plt.subplot(2,1,2)
plt.stem(n, x2, markerfmt='ro')
plt.plot(n_real, x2_real,'--')
plt.ylim([-1.5, 1.5])
plt.title('$x_2$')
plt.xlabel('n')
plt.show()

3.1. Frequency in Discrete Sinusoids

018π28π88π
In [15]:
N = 32

n = np.arange(0, 32)
x1 = np.cos(0*np.pi*n)
x2 = np.cos(1/8*np.pi*n)
x3 = np.cos(2/8*np.pi*n)
x4 = np.cos(1*np.pi*n)

# plot
plt.figure(figsize = (10, 8))
plt.subplot(4,1,1)
plt.stem(n, x1)
plt.xlim([0, 31])
plt.ylim([-1.5, 1.5])
plt.ylabel('0')

plt.subplot(4,1,2)
plt.stem(n, x2)
plt.xlim([0, 31])
plt.ylim([-1.5, 1.5])
plt.ylabel('1/8 $\pi$')

plt.subplot(4,1,3)
plt.stem(n, x3)
plt.xlim([0, 31])
plt.ylim([-1.5, 1.5])
plt.ylabel('2/8 $\pi$')

plt.subplot(4,1,4)
plt.stem(n, x4)
plt.xlim([0, 31])
plt.ylim([-1.5, 1.5])
plt.ylabel('8/8 $\pi$')
plt.show()
2π158π148π88π
In [16]:
n = np.arange(0, 32)
x5 = np.cos(2*np.pi*n)
x6 = np.cos(15/8*np.pi*n)
x7 = np.cos(14/8*np.pi*n)
x8 = np.cos(1*np.pi*n)

# plot
plt.figure(figsize = (10, 8))
plt.subplot(4,1,1)
plt.stem(n, x5)
plt.xlim([0, 31])
plt.ylim([-1.5, 1.5])
plt.ylabel('2')

plt.subplot(4,1,2)
plt.stem(n, x6)
plt.xlim([0, 31])
plt.ylim([-1.5, 1.5])
plt.ylabel('15/8 $\pi$')

plt.subplot(4,1,3)
plt.stem(n, x7)
plt.xlim([0, 31])
plt.ylim([-1.5, 1.5])
plt.ylabel('14/8 $\pi$')

plt.subplot(4,1,4)
plt.stem(n, x8)
plt.xlim([0, 31])
plt.ylim([-1.5, 1.5])
plt.ylabel('1 $\pi$')
plt.show()

3.2. Aliasing

Consider two sinusoids with two different frequencies


ωx1[n]=ej(ωn+ϕ)ω+2πx2[n]=ej((ω+2π)n+ϕ)=ej(ωn+ϕ)ej2πn
  • But note that
x2[n]=x1[n]
  • The signal x1 and x2 have different frequencies but are identical
  • We say that x1 and x2 are aliases; this phenomenon is called aliasing

Aliasing occurs when a system is measured at an insufficient sampling rate. It is perhaps best explained through an example.

In [17]:
t = np.linspace(0, 10*2*np.pi, 300)
x = np.sin(t)
y = np.cos(t)

# plot
plt.figure(figsize = (10, 8))
plt.subplot(2,1,1)
plt.plot(t, x, 'o')
plt.xlim([np.min(t), np.max(t)])
plt.ylabel('sin(t)')

plt.subplot(2,1,2)
plt.plot(t, y ,'o')
plt.ylabel('cos(t)')
plt.xlim([np.min(t), np.max(t)])
plt.show()
In [18]:
ts = np.linspace(0, 10*2*np.pi, 12)
xs = np.sin(ts)
ys = np.cos(ts)

# plot
plt.figure(figsize = (10, 8))
plt.subplot(2,1,1)
plt.plot(t, x)
plt.plot(ts, xs, 'o--')
plt.xlim([np.min(t), np.max(t)])
plt.ylabel('sin(t)')

plt.subplot(2,1,2)
plt.plot(t, y)
plt.plot(ts, ys, 'o--')
plt.ylabel('cos(t)')
plt.xlim([np.min(t), np.max(t)])
plt.show()
In [19]:
ts = np.linspace(0, 10*2*np.pi, 11)
xs = np.sin(ts)
ys = np.cos(ts)

# plot
plt.figure(figsize = (10, 8))
plt.subplot(2,1,1)
plt.plot(t, x)
plt.plot(ts, xs, 'o--')
plt.xlim([np.min(t), np.max(t)])
plt.ylabel('sin(t)')

plt.subplot(2,1,2)
plt.plot(t, y)
plt.plot(ts, ys, 'o--')
plt.ylabel('cos(t)')
plt.xlim([np.min(t), np.max(t)])
plt.show()
In [20]:
ts = np.linspace(0, 10*2*np.pi, 21)
xs = np.sin(ts)
ys = np.cos(ts)

# plot
plt.figure(figsize = (10, 8))
plt.subplot(2,1,1)
# plt.plot(t, x)
plt.plot(ts, xs, 'o--')
plt.xlim([np.min(t), np.max(t)])
plt.ylim([-1,1])
plt.ylabel('sin(t)')

plt.subplot(2,1,2)
# plt.plot(t, y)
plt.plot(ts, ys, 'o--')
plt.ylabel('cos(t)')
plt.xlim([np.min(t), np.max(t)])
plt.show()
In [2]:
%%html
<center><iframe 
width="560" height="315" src="https://www.youtube.com/embed/jHS9JGkEOmA?rel=0" frameborder="0" allowfullscreen>
</iframe></center>

4. Fourier Series

4.1. Delta Dirac Function

n=1,2,3,cos(nθ)=cosθ+cos2θ+cos3θ+
In [22]:
from scipy.fftpack import fft, ifft, fftshift

theta = np.linspace(0, 6*np.pi, 2**8)
x1 = np.cos(theta)

# plot
plt.figure(figsize = (10, 4))
plt.plot(theta, x1)
plt.ylim([-1.1, 1.1])
plt.xlim([np.min(theta), np.max(theta)])
plt.xlabel(r'$\theta$', fontsize = 15)
plt.show()
In [23]:
x2 = x1 + np.cos(2*theta)
x3 = x2 + np.cos(3*theta)
x4 = x3 + np.cos(4*theta)

# plot
plt.figure(figsize = (10,12))
plt.subplot(3,1,1)
plt.plot(theta, x2/2)
plt.xlim([np.min(theta), np.max(theta)])
plt.ylim([-1.1, 1.1])

plt.subplot(3,1,2)
plt.plot(theta, x3/3)
plt.xlim([np.min(theta), np.max(theta)])
plt.ylim([-1.1, 1.1])

plt.subplot(3,1,3)
plt.plot(theta, x4/4)
plt.xlim([np.min(theta), np.max(theta)])
plt.ylim([-1.1, 1.1])
plt.xlabel(r'$\theta$', fontsize = 15)
plt.show()
In [24]:
x = np.zeros(theta.shape)

N = 11000
for n in range(N):
    x = x + np.cos(n*theta)

# plot
plt.figure(figsize = (10, 4))
plt.plot(theta, x/N)
plt.xlabel(r'$\theta$', fontsize = 15)
plt.ylim([-1.1, 1.1])
plt.show()

4.2. Square Wave


n=1,3,5,4πnsin(nθ)=4πsinθ+43πsin3θ+45πsin5θ+


In [25]:
N = 2**8
theta = np.linspace(0, 2*np.pi, N)
x = np.zeros(theta.shape)

for n in range(1, 5000, 2):
    x = x + 4/(np.pi*n)*np.sin(n*theta)

# plot    
plt.figure(figsize = (10, 4))
plt.plot(theta/np.pi, x)
plt.xlabel(r'$\theta/\pi$', fontsize = 15)
plt.show()

4.3. How to Decompose a Signal into Fundamental Harmonic Sinusoids

  • Signal representation by harmonic sinusoids

  • Questions

    • how to decompose it to harmonic sinusoids
    • how to find the coefficients of harmonic sinusoids
    • how to find the frequency components
  • DFT or FFT can do such a job !!!

4.4. Fast Fourier Transformation (FFT)

  • FFT algorithms are so commonly employed to compute DFT that the term 'FFT' is often used to mean 'DFT'
    • The FFT has been called the "most important computational algorithm of our generation"
    • It uses the dynamic programming algorithm (or divide and conquer) to efficiently compute DFT.
  • DFT refers to a mathematical transformation or function, whereas 'FFT' refers to a specific family of algorithms for computing DFTs.
    • use fft command to compute dft
    • fft (computationally efficient)
  • We will use the embedded fft function without going too much into detail.
In [26]:
xt = fft(x, N)/N

# plot
plt.figure(figsize = (10, 4))
plt.stem(np.arange(0, N), np.abs(xt), 'b', markerfmt=' ')
plt.ylim([-0.01,1])
plt.xlabel('k')
plt.ylabel('|X[k]|')
plt.show()
n=1,3,5,4πnsin(nθ)=4πsinθ+43πsin3θ+45πsin5θ+
In [27]:
# plot
plt.figure(figsize = (10, 4))
plt.stem(np.arange(0, N), np.abs(xt))
plt.ylim([-0.01,1])
plt.xlabel('k')
plt.ylabel('|X[k]|')
plt.title('zoomed')
plt.xlim([0, 20])
plt.show()

Example


x[n]=ej2π8n


In [28]:
k = 1                  # index for frequency

N = 8
n = np.arange(0, N)    # sampling period

# harmonic complex exponential

x = np.exp(1j*2*np.pi/N*k*n) 
xt = fft(x)/N

# plot
plt.figure(figsize = (12,4))
plt.subplot(1,2,1)
plt.plot(np.real(x), np.imag(x), 'ko')
plt.axis('equal')
plt.xlabel('Real x')
plt.ylabel('Im x')
plt.title('$e^{j(2\pi/N) kn}$,   k = 1')

plt.subplot(1,2,2)
plt.stem(n, np.abs(xt))
plt.xlabel('k')
plt.ylabel('|X[k]|')
plt.title('Result of FFT')
plt.show()
x[n]=cos(2π8n)
In [29]:
k = 1                      # index for frequency

N = 8
n = np.arange(0, N)        # sampling period

x = np.exp(1j*2*np.pi/N*k*n) # np.cos(2*np.pi/N*k*n)  # harmonic complex exponential
Xt = fft(x)/N

# plot
plt.figure(figsize = (10,8))
plt.subplot(2,1,1)
plt.stem(n, np.real(x))
plt.xlim([0, 8])
plt.hlines(0,0,8, 'r')
plt.xlabel('n')
plt.ylabel('x[n]')
plt.title('$cos((2\pi/N) kn)$,   k = 1')

plt.subplot(2,1,2)
plt.stem(n, np.abs(Xt))
plt.xlim([0, 8])
plt.ylim([-0.1, 1])
plt.hlines(0,0,8, 'r')
plt.xlabel('k')
plt.ylabel('|X[k]|')
plt.title('Result of FFT')
plt.show()
  • Remember cosωt=eiωt+eiωt2
In [30]:
k = 1                      # index for frequency

N = 8
n = np.arange(0, N)        # sampling period

x = np.cos(2*np.pi/N*k*n)  # harmonic complex exponential

Xt = fft(x)/N
Xtshift = fftshift(Xt)

kr = np.hstack([np.arange(0, N/2), np.arange(-N/2, 0)])
ks = fftshift(kr)

# plot
plt.figure(figsize = (10,8))
plt.subplot(2,1,1)
plt.stem(n, np.abs(Xt))
plt.xlim([0, 8])
plt.ylim([-0.1, 1])
plt.xlabel('k')
plt.ylabel('|X[k]|')
plt.title('FFT')

plt.subplot(2,1,2)
plt.stem(ks, np.abs(Xtshift))
plt.xlim([-4, 4])
plt.ylim([-0.1, 1])
plt.xlabel('k')
plt.ylabel('|X[k]|')
plt.title('Shifted FFT')
plt.show()

5. FFT with Sampling Frequency

5.1. Implementing FFT routine


x[n]=0.7cos(2π60t)f=60


You can think this signal as a vibration signal from a rotating machinery with 60 Hz (or 60 × 60 = 3600 rpm)

In [31]:
Fs = 1000                # Sampling frequency                    
T = 1/Fs                 # Sampling period (or sampling interval)

N = 5000                 # Total data points (signal length)

t = np.arange(0, N)*T    # Time vector (time range)

k = np.arange(0, N)      # vector from 0 to N-1
f = (Fs/N)*k             # frequency range

x = np.cos(2*np.pi*60*t) 
xn = x + 1*np.random.randn(len(x))
In [32]:
plt.figure(figsize = (10, 4))
plt.plot(t, xn)
plt.xlim([0, 0.4])
plt.xlabel('t (sec)')
plt.show()
In [33]:
# original fft

xnt = fft(xn)/N
xntshift = fftshift(xnt)

kr = np.hstack([np.arange(0, N/2), np.arange(-N/2, 0)])
fr = (Fs/N)*kr
fs = fftshift(fr)

plt.figure(figsize = (10,8))
plt.subplot(2,1,1)
plt.plot(f, np.abs(xnt))
plt.ylabel('|X(f)|')
plt.ylim([0, 1.1])
plt.xlim([0, 1000])
plt.title('FFT')

plt.subplot(2,1,2)
plt.plot(fs, np.abs(xntshift))
plt.ylim([0, 1.1])
plt.xlim([-500, 500])
plt.xlabel('f')
plt.ylabel('|X(f)|')
plt.title('Shifted FFT')
plt.show()

5.2. Single-sided FFT (or Positive FFT)

  • Only want the first half of the FFT, since the last is redundant (symmetric)
  • 2 × amplitude except the DC component
In [34]:
# single-sides fft

xnt = fft(xn)/N
xntss = xnt[0:int(N/2)+1] # 0:N/2
xntss[1:-1] = 2*xntss[1:-1]

fss = f[0:int(N/2)+1]

plt.figure(figsize = (10,8))
plt.subplot(2,1,1)
plt.plot(fs, np.abs(xntshift))
plt.ylabel('|X(f)|')
plt.ylim([0, 1.1])
plt.xlim([-500, 500])
plt.title('Shifted FFT')

plt.subplot(2,1,2)
plt.plot(fss, np.abs(xntss))
plt.xlim([-500, 500])
plt.xlabel('f')
plt.ylabel('|X(f)|')
plt.ylim([0, 1.1])
plt.title('Single-sided FFT')
plt.show()

6. STFT (Short-Time Fourier Transform)

In [35]:
Fs = 2**10                   # Sampling frequency                    
T = 1/Fs                     # Sampling period (or sampling interval)

N = 2*Fs                     # Total data points (signal length)

t = np.arange(0, N)*T        # Time vector (time range)

k = np.arange(0, N)          # vector from 0 to N-1
f = (Fs/N)*k                 # frequency range

x1 = np.cos(2*np.pi*50*t)
x2 = np.cos(2*np.pi*100*t)

x = np.zeros(t.shape)
x[0:int(N/2)] = x1[0:int(N/2)]
x[int(N/2):-1] = x2[int(N/2):-1]
In [36]:
plt.figure(figsize = (10,8))
plt.subplot(2,1,1)
plt.plot(t, x)
plt.xlabel('t')
plt.ylabel('x(t)')
plt.xlim([np.min(t), np.max(t)])

plt.subplot(2,1,2)
plt.plot(t, x)
plt.xlim([0.9, 1.1])
plt.xlabel('t')
plt.ylabel('x(t)')
plt.show()
In [37]:
z = 1/2*(x1 + x2)

plt.figure(figsize = (10,8))
plt.plot(t, z)
plt.xlabel('t')
plt.ylabel('x(t)')
plt.xlim([0.9,1.1])
plt.ylim([-1,1])

plt.show()

FFT does not provide time information of the signal.

In [38]:
xt = fft(x)/N

plt.figure(figsize = (10,8))
plt.subplot(2,1,1)
plt.plot(f, np.abs(xt))
plt.ylim([-0.05,1])
plt.ylabel('|X(f)|')
plt.xlim([np.min(f), np.max(f)])

plt.subplot(2,1,2)
plt.plot(f, np.abs(xt))
plt.xlim([0, 300])
plt.ylim([-0.05,1])
plt.xlabel('f')
plt.ylabel('|X(f)|')
plt.title('zoomed')
plt.show()
In [39]:
zt = fft(z)/N

plt.figure(figsize = (10,8))
plt.subplot(2,1,1)
plt.plot(f, np.abs(zt))
plt.ylim([-0.05,1])
plt.ylabel('|X(f)|')
plt.xlim([np.min(f), np.max(f)])

plt.subplot(2,1,2)
plt.plot(f, np.abs(zt))
plt.xlim([0, 300])
plt.ylim([-0.05,1])
plt.xlabel('f')
plt.ylabel('|X(f)|')
plt.title('zoomed')
plt.show()
  • The spectral content of speech changes over time (non-stationary)
    • As an example, formants change as a function of the spoken phonemes
    • Applying the DFT over a long window does not reveal transitions in spectral content
  • To avoid this issue, we apply the DFT over short periods of time
    • For short enough windows, speech can be considered to be stationary
    • Remember, though, that there is a time-frequency tradeoff here!

In [40]:
from scipy.signal import spectrogram

windowsize = 2**7 
window = np.hanning(windowsize) 
nfft = windowsize 
noverlap = windowsize/2 

f, t, Sxx = spectrogram(z, 
                        Fs, 
                        window = window, 
                        noverlap = noverlap,
                        nfft = nfft, 
                        scaling = 'spectrum',
                        mode = 'psd') 

plt.figure(figsize = (6, 6))
plt.pcolormesh(t, f, Sxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()
In [41]:
Sxx.shape
Out[41]:
(65, 31)
In [42]:
from scipy.signal import spectrogram

windowsize = 2**8 # 조정가능
window = np.hanning(windowsize) # fix
nfft = windowsize # fix
noverlap = windowsize/2 # fix

f, t, Sxx = spectrogram(z, # time domain signal
                        Fs, # sampling rate
                        window = window, # fix
                        noverlap = noverlap, # fix
                        nfft = nfft, # fix
                        scaling = 'spectrum', # fix
                        mode = 'psd') # fix

plt.figure(figsize = (6, 6))
plt.pcolormesh(t, f, Sxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()
In [43]:
Sxx.shape
Out[43]:
(129, 15)
In [44]:
f, t, Sxx = spectrogram(x, 
                        Fs, 
                        window = window, 
                        noverlap = noverlap, 
                        nfft = nfft, 
                        scaling = 'spectrum', 
                        mode = 'psd')

plt.figure(figsize = (6, 6))
plt.pcolormesh(t, f, Sxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()
In [45]:
windowsize = 2**8
window = np.hanning(windowsize)
nfft = windowsize
noverlap = windowsize/2

f, t, Sxx = spectrogram(x, 
                        Fs, 
                        window = window, 
                        noverlap = noverlap, 
                        nfft = nfft, 
                        scaling = 'spectrum', 
                        mode = 'psd')

plt.figure(figsize = (6, 6))
plt.pcolormesh(t, f, Sxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()

Chirp

x[n]=0.3cos(2π3000000n2)
In [46]:
# chirp (https://en.wikipedia.org/wiki/Chirp)
n = np.arange(0,44100*2)
fs = 44100
chirp = 0.3*np.cos(2*np.pi/3000000*n**2)

# plot
plt.figure(figsize = (10, 4))
plt.plot(n/fs, chirp)
plt.xlim([0, 0.4])
plt.show()
In [47]:
Audio(chirp, rate = fs)
Out[47]:
In [48]:
# chirp (https://en.wikipedia.org/wiki/Chirp)

windowsize = 2**8
window = np.hanning(windowsize)
nfft = windowsize
noverlap = windowsize/2

f, t, Sxx = spectrogram(chirp, 
                        fs, 
                        window = window, 
                        noverlap = noverlap, 
                        nfft = nfft, 
                        scaling = 'spectrum', 
                        mode = 'psd')

plt.figure(figsize = (6, 6))
plt.pcolormesh(t, f, Sxx)
plt.ylabel('Frequency [Hz]')
plt.xlabel('Time [sec]')
plt.show()
In [53]:
%%javascript
$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')