Fourierov integral

Primjer snimanja signala, numeričkog računanja Fourierovog integrala, i rekonstrukcije signala nakon rezanja frekvencija.


In [1]:
using PortAudio, SampledSignals, LibSndFile
using FileIO: load, save, loadstreaming, savestreaming
using QuadGK

In [2]:
PortAudio.devices()


Out[2]:
13-element Array{PortAudio.PortAudioDevice,1}:
 PortAudio.PortAudioDevice("Microsoft Sound Mapper - Input", "MME", 2, 0, 44100.0, 0, 0.09, 0.09, 0.18, 0.18)
 PortAudio.PortAudioDevice("Microphone (Realtek High Defini", "MME", 2, 0, 44100.0, 1, 0.09, 0.09, 0.18, 0.18)
 PortAudio.PortAudioDevice("Microsoft Sound Mapper - Output", "MME", 0, 2, 44100.0, 2, 0.09, 0.09, 0.18, 0.18)
 PortAudio.PortAudioDevice("Speaker/Headphone (Realtek High", "MME", 0, 2, 44100.0, 3, 0.09, 0.09, 0.18, 0.18)
 PortAudio.PortAudioDevice("Speakers ()", "Windows WDM-KS", 0, 2, 44100.0, 4, 0.01, 0.01, 0.08533333333333333, 0.08533333333333333)
 PortAudio.PortAudioDevice("Microphone (Realtek HD Audio Mic input)", "Windows WDM-KS", 2, 0, 44100.0, 5, 0.01, 0.01, 0.04, 0.04)
 PortAudio.PortAudioDevice("Mic in at front panel (black) (Mic in at front panel (black))", "Windows WDM-KS", 2, 0, 44100.0, 6, 0.01, 0.01, 0.04, 0.04)
 PortAudio.PortAudioDevice("Speakers (Realtek HD Audio output)", "Windows WDM-KS", 0, 2, 44100.0, 7, 0.01, 0.01, 0.04, 0.04)
 PortAudio.PortAudioDevice("Stereo Mix (Realtek HD Audio Stereo input)", "Windows WDM-KS", 2, 0, 48000.0, 8, 0.01, 0.01, 0.04, 0.04)
 PortAudio.PortAudioDevice("Output (@System32\\drivers\\bthhfenum.sys,#4;%1 Hands-Free HF Audio%0\r\n;(iPhone))", "Windows WDM-KS", 0, 1, 8000.0, 9, 0.01, 0.01, 0.08533333333333333, 0.08533333333333333)
 PortAudio.PortAudioDevice("Input (@System32\\drivers\\bthhfenum.sys,#4;%1 Hands-Free HF Audio%0\r\n;(iPhone))", "Windows WDM-KS", 1, 0, 8000.0, 10, 0.01, 0.01, 0.08533333333333333, 0.08533333333333333)
 PortAudio.PortAudioDevice("Headset Earphone (@System32\\drivers\\bthhfenum.sys,#2;%1 Hands-Free AG Audio%0\r\n;(JBL Charge 3))", "Windows WDM-KS", 0, 1, 8000.0, 11, 0.01, 0.01, 0.08533333333333333, 0.08533333333333333)
 PortAudio.PortAudioDevice("Headset Microphone (@System32\\drivers\\bthhfenum.sys,#2;%1 Hands-Free AG Audio%0\r\n;(JBL Charge 3))", "Windows WDM-KS", 1, 0, 8000.0, 12, 0.01, 0.01, 0.08533333333333333, 0.08533333333333333)

Nakon što ste pronašli vaše uređaje, možete otkomentirati sljedeću ćeliju u kojoj se ulaz s mikrofona direktno prenosi na zvučnik. Nakon toga treba ponovo pokrenuti jezgru.


In [3]:
#=
stream = PortAudioStream(2, 2)
try
    # cancel with Ctrl-C
    write(stream, stream)
finally
    close(stream)
end
=#

Ukoliko želite snimiti svoj tekst, zamijenite mikrofon i izlaz s vašim uređajima, i izvedite sljedeće četiri čelije.


In [6]:
# stream = PortAudioStream("Microphone (BRIO 4K Stream Edit","Microsoft Sound Mapper - Output")


Out[6]:
PortAudioStream{Float32}
  Samplerate: 44100.0Hz

  2 channel sink: "Microsoft Sound Mapper - Output"
  2 channel source: "Microphone (BRIO 4K Stream Edit"

In [7]:
# Namjestite duljinu snimke (nemojte pretjerivati)
# buf = read(stream, 2s)


Out[7]:

In [8]:
# Zatvorite stream
# close(stream)

In [9]:
# Spremite vašu snimku
# save("myvoice.wav", buf)

In [4]:
glas=load("myvoice.wav")


Out[4]:

In [5]:
length(glas)


Out[5]:
176400

In [6]:
glas.samplerate


Out[6]:
44100.0

In [7]:
typeof(glas)


Out[7]:
SampleBuf{Float32,2}

In [8]:
# Napravimo mono snimku
glas_mono=similar(glas)


Out[8]:

In [9]:
glas_mono.data=sum(glas.data,dims=2)
glas_mono.samplerate=glas.samplerate


Out[9]:
44100.0

In [10]:
save("myvoice_mono.wav", glas_mono)

In [11]:
glas_mono.data


Out[11]:
88200×1 Array{Float32,2}:
 -0.00015258789
 -9.1552734f-5
 -6.1035156f-5
 -9.1552734f-5
 -3.0517578f-5
  6.1035156f-5
  0.00015258789
  9.1552734f-5
  0.0
  0.0
  0.0
  3.0517578f-5
  0.0
  ⋮
 -3.0517578f-5
 -0.0011291504
 -0.0039367676
 -0.006164551
 -0.007843018
 -0.009490967
 -0.011474609
 -0.0146484375
 -0.018371582
 -0.020141602
 -0.0211792
 -0.023773193

In [12]:
# Pogledajmo signal
using Plots

In [14]:
S=glas_mono.data
plot(S)


Out[14]:

In [103]:
plot(T,S)


Out[103]:

In [18]:
# Trapezna formula, približno. Računamo kosinusni i sinusni spektar
using LinearAlgebra
A(λ::Float64)=(cos.(λ*T)S)*((T[end]-T[1])/(length(T)*π))
B(λ::Float64)=(sin.(λ*T)S)*((T[end]-T[1])/(length(T)*π))


Out[18]:
B (generic function with 1 method)

In [19]:
# Nacrtajmo kosinusni spektar i odlučimo gdje koje frekvencije ćemo zadržati
plot(B,300,5000)


Out[19]:

In [20]:
# Ograničimo spektar, opet koristimo približnu formulu
λ₀=600.0
λ₁=4500.0
step=0.5
Λ=range(λ₀,λ₁,step=step)
# Ovo traje cca 1 minutu, ali se računa samo jednom
=A.(Λ)
=B.(Λ)


Out[20]:
7801-element Array{Float64,1}:
 -1.4276545343692649e-5
  6.9369216861432245e-6
  2.112717985256516e-5
  3.123817843795039e-5
  4.1020107290376104e-5
  4.6898213248294996e-5
  3.876846443879242e-5
  1.0373092159497102e-5
 -3.040583150749619e-5
 -6.26014173311179e-5
 -6.625478447345567e-5
 -3.870254324568669e-5
  1.4653952013808025e-6
  ⋮
  1.7794981642116358e-5
  9.992730104962406e-7
 -1.277551704963596e-5
 -1.5925982443486848e-5
 -4.188816410633976e-6
  1.9864473329428913e-5
  4.641590648579104e-5
  6.2524350825799e-5
  5.901390212558618e-5
  3.584836468909258e-5
  2.2516323865110587e-6
 -2.8636014669379933e-5

In [167]:
g(x::Float64)=(Aλ⋅cos.(x*Λ)+Bλ⋅sin.(x*Λ))*step


Out[167]:
g (generic function with 2 methods)

In [21]:
# Rekonstruirajmo signal s odrezanim frekvencijama
g(x::Float64)=(Aλ⋅cos.(x*Λ)+Bλ⋅sin.(x*Λ))*step
G=g.(T)


Out[21]:
88200-element Array{Float64,1}:
  0.000184805327142117
  0.00022355499304577928
  0.00026082494707742234
  0.0002962364964993873
  0.00032942895326896885
  0.0003600634641776046
  0.00038782662073811507
  0.0004124338106432171
  0.00043363227525326325
  0.0004512038405850413
  0.0004649672926284134
  0.0004747803714866872
  0.00048054136277459234
  ⋮
  0.0014759800471028286
 -0.00017988954098602
 -0.0017398810480251034
 -0.003200230175866396
 -0.00455783291565055
 -0.005810252841406547
 -0.006955723797088994
 -0.007993148002196426
 -0.008922089635965701
 -0.009742763993387377
 -0.010456022339221955
 -0.011063332617785724

In [22]:
# Usporedimo grafički
plot(T,[S G],layout=(2,1))


Out[22]:

In [23]:
# Spremimo signal s odrezanim frekvencijama i poslušajmo
glas_mono_odrezan=deepcopy(glas_mono)
glas_mono_odrezan.data[:,1]=map(Float32,G)
save("myvoice_odrezan.wav", glas_mono_odrezan)

In [24]:
glas_mono_odrezan


Out[24]: