Solutions 8 - Examples in Signal Decomposition


Assignment 1


In [1]:
# Packages
using WAV
using LinearAlgebra
using FFTW
using SpecialMatrices
using LinearMaps
using Plots
using Arpack

In [2]:
s, Fs = wavread("files/piano_A41.wav",100001);

In [3]:
Fs


Out[3]:
44100.0f0

In [3]:
# wavplay(s,Fs)

In [4]:
function monocomponents(x::Array{Float64}, xx::Array{Float64}, Fs::Float32, k::Int64, d::Int64)
    # w is output from wavread(), package WAV, m is the number of samples we actually take
    # x=vec(s) where s is the output of wavread()
    # Fs is the output of wavread()
    # k (even) is the number of eigenpairs computed by eigs()
    # d is the level of recursion 
    # x=vec(s) where s is the output of wavread()
    # There is no grouping of repeating components! 
    println("d = ",d)
    if d<=2
        H=Hankel(x)
        n=size(H,1)
        xsimple=Array{Float64}(undef,2*n-1)
        # Fast Hankel EVD solver
        f(x)=H*x
        A=LinearMap(f,n,issymmetric=true)
        λ,U=eigs(A, nev=k, which=:LM)
        # @show λ
        # Significant threshold percentage test
        τ=0.1
        L=map(Int,round((sum(abs.(λ).>(τ*maximum(abs.(λ))))/2)))
        if L==1
            @show L
            # Return the signal as monocomponent. 
            # The signal is reconstructed using only ONE element of the skew-diagonals
            xsimple=[(λ[1]*U[1,1])*U[:,1]; (λ[1]*U[n,1])*U[2:n,1]]
            xsimple+=[(λ[2]*U[1,2])*U[:,2]; (λ[2]*U[n,2])*U[2:n,2]]
            xx=[xx xsimple]
        else
            d+=1
            # Analyze the i-th component
            for i=1:L
                # how L,i
                l1=2*i-1
                l2=2*i
                xsimple=[(λ[l1]*U[1,l1])*U[:,l1]; (λ[l1]*U[n,l1])*U[2:n,l1]]
                xsimple+=[(λ[l2]*U[1,l2])*U[:,l2]; (λ[l2]*U[n,l2])*U[2:n,l2]]
                # Recursion - we do not need more than 2*L eigenpairs
                xx=monocomponents(xsimple,xx, Fs,2*L,d)
            end
        end
    end
    xx
end


Out[4]:
monocomponents (generic function with 1 method)

In [5]:
x=vec(s)
xx=x
k=40
xmono=monocomponents(x,xx,Fs,k,0)


d = 0
d = 1
L = 1
d = 1
d = 2
L = 1
d = 2
d = 3
d = 3
d = 1
L = 1
d = 1
d = 2
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 1
d = 2
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 1
d = 2
d = 3
d = 3
d = 2
L = 1
d = 2
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 3
d = 1
d = 2
L = 1
d = 2
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 3
d = 1
d = 2
d = 3
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 3
d = 1
L = 1
d = 1
d = 2
L = 1
d = 2
d = 3
d = 3
d = 3
d = 2
d = 3
d = 3
d = 3
d = 1
d = 2
L = 1
d = 2
d = 3
d = 3
Out[5]:
100001×9 Array{Float64,2}:
 -0.0101321    0.16594     -0.0286502    …   0.0123591     0.000295601
 -0.0102542    0.187282     0.00178125       0.0133124     0.00424546
 -0.0102542    0.207883     0.032182         0.01343       0.00759957
 -0.0101321    0.227664     0.0620733        0.0127046     0.00988739
 -0.00994903   0.246545     0.0909844        0.0111816     0.010788
 -0.00964385   0.264452     0.11846      …   0.00895679    0.0101751
 -0.00933866   0.281316     0.144067         0.00616982    0.00813481
 -0.00909452   0.297069     0.167403         0.00299568    0.00495332
 -0.00878933   0.311651     0.188101        -0.000366362   0.00107704
 -0.00860622   0.325003     0.205834        -0.00370524   -0.0029502
 -0.00842311   0.337073     0.220323     …  -0.00681135   -0.00656339
 -0.00799585   0.347815     0.231341        -0.00948973   -0.00925566
 -0.00720237   0.357185     0.238715        -0.0115723    -0.0106493
  ⋮                                      ⋱                
  0.00335704   0.00574434  -0.00035953      -0.00051404   -0.000115165
  0.00317392   0.00559052  -0.000868842  …  -0.000150901   0.000554123
  0.00286874   0.00541471  -0.00136442       0.000221692   0.00114565
  0.00231941   0.00521759  -0.00183847       0.000580351   0.00157642
  0.00152593   0.00499994  -0.00228353       0.00090256    0.00178603
  0.000549333  0.00476263  -0.00269258       0.00116809    0.00174506
 -0.000427259  0.00450658  -0.00305918   …   0.00136029    0.00145927
 -0.00134281   0.00423282  -0.00337757       0.00146708    0.000968778
 -0.0021363    0.00394242  -0.00364273       0.00148177    0.000342389
 -0.00262459   0.00363653  -0.0038505        0.00140345   -0.000332009
 -0.00286874   0.00331635  -0.0039976        0.00123702   -0.000959804
 -0.00305185   0.00298315  -0.00408173   …   0.000992949  -0.00145292

We computed 8 mono-components (xmono[:,1] is the original signal).

Let us plot and listen to the mono-components.


In [6]:
norm(x-xmono[:,1])


Out[6]:
0.0

In [9]:
k=6
plot(xmono[:,k][1:400])


Out[9]:

In [14]:
t=range(0,stop=length(s)/Fs,length=length(s))


Out[14]:
0.0f0:2.2675966f-5:2.2675965f0

In [30]:
l=10000
k=9
fs=abs.(fft(xmono[:,k]))
m,ind=findmax(fs[1:l])
println("Frequency = ", ind*Fs/length(fs)  ," Hz, Amplitude = ", m)
plot(t[1:l],fs[1:l])


Frequency = 2645.0916 Hz, Amplitude = 217.0867864342128
Out[30]:


In [9]:
wavplay(xmono[:,k],Fs)

In [10]:
xx=sum(xmono[:,2:9],dims=2)
wavplay(xx,Fs)

In [ ]: