Advertisement
Guest User

Untitled

a guest
Jun 24th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.79 KB | None | 0 0
  1. ## Importations utiles
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import random
  5. from scipy.signal import stft
  6. from scipy.signal import square
  7. from scipy.io.wavfile import read
  8. from scipy.io.wavfile import write
  9. from contextlib import contextmanager
  10. from matplotlib import cm
  11. from numpy import NaN
  12. import math
  13. from matplotlib import ticker
  14. from matplotlib.colors import LightSource
  15. from scipy.signal import istft
  16. from scipy.signal import correlate
  17. from mpl_toolkits.mplot3d import Axes3D
  18. import cmath as cm
  19. from scipy import stats
  20. import matplotlib
  21. from matplotlib.ticker import LinearLocator, FormatStrFormatter
  22. import time
  23. import pyroomacoustics as pra
  24. from scipy.io import wavfile
  25.  
  26. ################################################
  27.  
  28. ## LI-TEMPROM
  29. def calc_moyenneTEMP(rapp,M,i):
  30.     moy = 0
  31.     for j in range(0,M):
  32.         moy = moy + rapp[int(i*M/2 + j)]
  33.     moy = 1/M * moy
  34.     return moy
  35.  
  36. def calc_varianceTEMP(rapp,M,i): # calcul la variance de rapp pour la ieme fenêtre
  37.                                # de longueur M, à la fréquence num f
  38.     moy = 0
  39.     for j in range(0,M):
  40.         moy = moy + rapp[int(i*M/2 + j)]
  41.     moy = 1/M * moy
  42.  
  43.     var = 0
  44.    
  45.     for j in range(0,M):
  46.         var = var + abs(rapp[int(i*M/2 + j)] - moy)**2
  47.     var = 1/M * var
  48.     return var
  49.  
  50. def varianceTEMP(rapp,M):
  51.     k = 0
  52.     nb_tps = len(rapp)
  53.     nb_fenetre = 0
  54.    
  55.     while k < (nb_tps - M): # donne le nb de fenêtre temporelles à analyser
  56.         nb_fenetre = nb_fenetre + 1
  57.         k = k + M/2
  58.    
  59.     res = np.zeros((nb_fenetre,2))
  60.                                         # pos 0 : num fenêtre
  61.                                         # pos 1 : variance
  62.    
  63.     for i in range(0,nb_fenetre):
  64.             res[i][1] = calc_varianceTEMP(rapp,M,i)
  65.             res[i][0] = i
  66.    
  67.     return res,nb_fenetre
  68.  
  69. def rapportTEMP(melange1,melange2):
  70.     long = len(melange1)
  71.     res = np.zeros(long)
  72.     for i in range(long):
  73.         res[i] = NaN
  74.         if melange2[i] != 0:
  75.             res[i] = melange1[i]/melange2[i]
  76.     return res
  77.  
  78. def CL(coeff1,signal1,coeff2,signal2): #Effectue le mélange
  79.     res = np.add(coeff1 * signal1,coeff2 * signal2)
  80.     return res
  81.  
  82. def rapportbis(melange1,melange2):
  83.     long = len(melange1)
  84.     res = np.zeros(long)
  85.     for i in range(long):
  86.         if melange2[i] != 0:
  87.             res[i] = melange1[i]/melange2[i]
  88.     return res
  89.  
  90.  
  91. def creernuage(rapp_trie,var_max,x1,x2,M):
  92.     x1_res = []
  93.     x2_res = []
  94.     i = 0
  95.     n = len(rapp_trie)
  96.     while i < n and rapp_trie[i][1] < var_max:
  97.         x1_res.append(x1[int(rapp_trie[i][0] * M/2)])
  98.         x2_res.append(x2[int(rapp_trie[i][0] * M/2)])
  99.         i = i + 1
  100.        
  101.     return x1_res,x2_res
  102.  
  103. x1_res,x2_res = creernuage(rapp_trie,1e-14,x1,x2,8)
  104.  
  105. ## LI-TIFROM
  106. # Calculer rapport de deux stft de mélanges
  107. def rapport(stft_x1,stft_x2,freq_echant):
  108.     nb_freq,nb_tps = stft_x1.shape
  109.     res = np.zeros((nb_freq,nb_tps))
  110.     for f in range(0,nb_freq):
  111.         for n in range(0,nb_tps):
  112.             if stft_x2[f][n] != 0:
  113.                 res[f][n] = stft_x1[f][n]/stft_x2[f][n]
  114.             else:
  115.                 res[f][n] = NaN
  116.     return res
  117.  
  118. #Calculer variance du rapport DE DEUX MELANGES SEULMENT pour chaque fréquence
  119.  
  120. # fenêtre temporelle de longueur M, supposé pair
  121.  
  122. def calc_moyenne(rapp,M,f,i):
  123.     moy = 0
  124.     for j in range(0,M):
  125.         moy = moy + rapp[f][int(i*M/2 + j)]
  126.     moy = 1/M * moy
  127.     return moy
  128.  
  129. def calc_variance(rapp,M,f,i): # calcul la variance de rapp pour la ieme fenêtre
  130.                                # de longueur M, à la fréquence num f
  131.     moy = 0
  132.     for j in range(0,M):
  133.         moy = moy + rapp[f][int(i*M/2 + j)]
  134.     moy = 1/M * moy
  135.  
  136.     var = 0
  137.    
  138.     for j in range(0,M):
  139.         var = var + np.abs(rapp[f][int(i*M/2 + j)] - moy)**2
  140.     var = 1/M * var
  141.     return var
  142.  
  143. # i : INDIQUE LE NUMERO DE LA FENETRE
  144.  
  145. def variance(rapp,M): #renvoie une matrice de taille nb_freq * nb_fenetre
  146.                       #donnant la variance pour chaque fenêtre,fréquence.
  147.     nb_freq,nb_tps = rapp.shape
  148.     nb_fenetre = 0
  149.     k = 0
  150.    
  151.     while k < (nb_tps - M): # donne le nb de fenêtre temporelles à analyser
  152.         nb_fenetre = nb_fenetre + 1
  153.         k = k + M/2
  154.  
  155.     res = np.zeros((nb_freq,nb_fenetre,3),dtype=object)
  156.                                         # pos 0 : num fréquence (=/= freq réelle)
  157.                                         # pos 1 : num fenêtre
  158.                                         # pos 2 : variance
  159.    
  160.     for i in range(0,nb_fenetre):
  161.         for f in range(0,nb_freq):
  162.             res[f][i][2] = calc_variance(rapp,M,f,i)
  163.             res[f][i][0] = f
  164.             res[f][i][1] = i
  165.    
  166.     return res,nb_fenetre
  167.  
  168. # Tri
  169.  
  170. def trier(A): # A = matrice de taille nb_freq * nb_fen * 3
  171.               # Renvoie une liste de longueur nb_freq * nb_fen triée selon la
  172.               # variance croissante
  173.     atrier = np.reshape(A,(len(A)*len(A[0]),3))
  174.     atrier = atrier[np.argsort(atrier[:,2])]
  175.     return atrier # atrier = tableau des variances triées
  176.  
  177. # Détection des sources visibles, détection des zones mono-sources
  178.  
  179. # rapp : rapport de deux mélanges
  180. # tabvar : tableau des variances croissantes associé
  181. def detecter_sources_visibles(rapp,tabvar,variance_max,seuil,M,N):
  182.     res = []
  183.     indicemax_tabvar = 0 # Indice de la zone limite considérée (var assez faible).
  184.     n = len(tabvar)
  185.     while indicemax_tabvar < (n-1):
  186.         if tabvar[indicemax_tabvar + 1][2] < variance_max:
  187.             indicemax_tabvar = indicemax_tabvar + 1
  188.         else:
  189.             break
  190.    
  191.     rapports_seuls = np.copy(tabvar[0:indicemax_tabvar + 1])
  192.     num_source = np.zeros(indicemax_tabvar + 1,dtype = int)
  193.             # Contient pour chaque rapport le numéro de la source associé
  194.             # (complété au fur et à mesure après)
  195.    
  196.    
  197.     # On remplace la variance par les rapports dans rapports_seuls
  198.     for i in range(0,indicemax_tabvar + 1):
  199.         rapports_seuls[i][2] = \
  200.                 calc_moyenne(rapp,M,rapports_seuls[i][0],rapports_seuls[i][1])
  201.                
  202.     res.append([[rapports_seuls[0][0],rapports_seuls[0][1]]]) #Initialisation de res
  203.    
  204.     for i in range(1,indicemax_tabvar + 1):
  205.         indice_memesource = -1 # Indice où la source seule est identique.
  206.         for k in range(0,i):
  207.             if np.abs(rapports_seuls[i][2] - rapports_seuls[k][2]) < seuil:
  208.                 indice_memesource = k
  209.                 break
  210.                
  211.         if indice_memesource != -1:
  212.             if len(res[num_source[indice_memesource]]) < 15:
  213.                 res[num_source[indice_memesource]].append([rapports_seuls[i][0],rapports_seuls[i][1]])
  214.                 num_source[i] = num_source[indice_memesource]
  215.             else:
  216.                 rapports_seuls[i][2] = NaN
  217.        
  218.         else:
  219.             if len(res) < N:
  220.                 res.append([[rapports_seuls[i][0],rapports_seuls[i][1]]])
  221.                 num_source[i] = len(res) - 1
  222.             else:
  223.                 rapports_seuls[i][2] = NaN
  224.  
  225.     nb_rapports = 0
  226.     for k in res:
  227.         nb_rapports = nb_rapports + len(k)
  228.    
  229.     rapports_seuls_new = np.empty((nb_rapports,3), dtype=np.object)
  230.     count = 0
  231.     for k in rapports_seuls:
  232.         if not math.isnan(k[2]):
  233.             rapports_seuls_new[count] = k
  234.             count = count + 1
  235.  
  236.     return res,indicemax_tabvar,rapports_seuls_new
  237.  
  238.     # res : matrice de taille nb_sources_vis * ? * 2
  239.     #       donnant toutes les zones mono-sources par source.
  240.     #       Le "?" change selon la source, mais minimum 1.
  241.     #       - Colonne 0 : num fréquence.
  242.     #       - Colonne 1 : num fenêtre temporelle.
  243.  
  244.  
  245. # Calcul moyenne du rapport entre deux mélanges en une zone monosource
  246.  
  247. #i : num de la fenêtre temporelle
  248. def calc_moy_monosource(stft_x1,stft_x2,M,f,i):
  249.     moy = 0
  250.     for k in range(0,M):
  251.         moy = moy + stft_x1[f][int(M/2 * i + k)]/stft_x2[f][int(M/2 * i + k)]
  252.     moy = 1/M * moy
  253.     return moy
  254.  
  255.  
  256. # Cas N = Q = P
  257. # où N = nb de sources ; Q = nb de sources visibles ; P = nb de mélanges.
  258. #matrice_rapports = le res du résultat précédent
  259. #melanges = matrice contenant tous les STFT des mélanges 0,..,(N-1).
  260.  
  261. def creer_mat_mixage(N,matrice_rapports,rapp,M):
  262.     if N != len(matrice_rapports):
  263.         return False
  264.    
  265.     else:
  266.         mat_mixage = np.zeros((N,N))
  267.    
  268.         for j in range(0,N):        # 1ere ligne
  269.             mat_mixage[0][j] = 1
  270.    
  271.         for i in range(1,N):
  272.             for j in range(0,N):    # Case i,j
  273.                 nb_cij = 0
  274.                 for L in matrice_rapports[j]:
  275.                     nb_cij = nb_cij + np.mean(rapp[L[0]][int(M/2)*L[1]:int(M/2)*L[1]+M])
  276.                
  277.                 mat_mixage[i][j] = nb_cij/len(matrice_rapports[j])
  278.         return mat_mixage
  279.  
  280. def retrouver_sources(mat_mixage,melanges):
  281.     return np.dot(np.linalg.inv(mat_mixage),melanges)
  282.  
  283. def wav_sourcesbis(mat_sources_separees,freq_echant):
  284.     N = len(mat_sources_separees)
  285.     for i in range(0,N):
  286.         write("/home/felix/sourceseparee%d.wav" %i,freq_echant,
  287.         mat_sources_separees[i])
  288.  
  289.  
  290. ### LI-TIFROM retardé
  291.  
  292. def detecter_sources_visibles_freq(rapp,correlation_max,M,temps_stft,freq_stft,stft_melanges):
  293.    
  294.     var_freq = variance_freq(rapp,M)
  295.     tabvar = np.reshape(var_freq,(len(var_freq)*len(var_freq[0]),3))
  296.     tabvar = tabvar[np.argsort(tabvar[:,2])]#[::-1]
  297.    
  298.     # tabvar de longueur nb_fenetre * nb_tps et contenant les [t,fi,var] trié
  299.     # par variance croissante.
  300.    
  301.     return tabvar
  302.  
  303. def variance_freq(rapp,M): #renvoie une matrice de taille nb_fenetre * nb_tps
  304.                            #donnant la variance pour chaque fenêtre (à temps CSTE).
  305.     nb_freq,nb_tps = rapp.shape
  306.     nb_fenetre = 0
  307.     k = 0
  308.    
  309.     while k < (nb_freq - M): # donne le nb de fenêtre fréquentielles à analyser
  310.         nb_fenetre = nb_fenetre + 1
  311.         k = k + M/2
  312.  
  313.     res = np.zeros((nb_tps,nb_fenetre,3),dtype=object)
  314.                                         # pos 0 : num temps (=/= temps réel)
  315.                                         # pos 1 : num fenêtre en fréquence
  316.                                         # pos 2 : variance
  317.    
  318.     for t in range(0,nb_tps):
  319.         for fi in range(0,nb_fenetre):
  320.             res[t][fi][2] = calc_variance_freq(rapp,M,fi,t)
  321.             res[t][fi][1] = fi
  322.             res[t][fi][0] = t
  323.    
  324.     return res
  325.  
  326.  
  327. def calc_variance_freq(rapp,M,fi,t): # calcul la variance de rapp pour la
  328.                                      # fi-eme fenêtre fréquentielle
  329.                                      # de longueur M, au temps t
  330.     moy = 0
  331.     for j in range(0,M):
  332.         moy = moy + np.abs(rapp[int(fi*M/2 + j)][t])
  333.     moy = 1/M * moy
  334.  
  335.     var = 0
  336.    
  337.     for j in range(0,M):
  338.         var = var + np.abs(np.abs(rapp[int(fi*M/2 + j)][t]) - moy)**2
  339.     var = 1/M * var
  340.     return var
  341.  
  342. def calc_moyenne_freq(rapp,M,fi,t):
  343.     moy = 0
  344.     for j in range(0,M):
  345.         moy = moy + np.abs(rapp[int(fi*M/2 + j)][t])
  346.     moy = 1/M * moy
  347.     return moy
  348.  
  349. def rapport_freq(stft_x1,stft_x2,freq_echant):
  350.     nb_freq,nb_tps = stft_x1.shape
  351.     res = np.zeros((nb_freq,nb_tps),dtype=complex)
  352.     for f in range(0,nb_freq):
  353.         for n in range(0,nb_tps):
  354.             if stft_x2[f][n] != 0:
  355.                 res[f][n] = stft_x1[f][n]/stft_x2[f][n]
  356.             else:
  357.                 res[f][n] = NaN
  358.     return res
  359.  
  360. def modifier_stft(Zxx,L,M):
  361.     nb_freq,nb_tps = Zxx.shape
  362.     res = np.zeros(np.shape(Zxx),dtype=complex)
  363.     for k in L:
  364.         f = k[0]
  365.         t = int(M/2) * k[1]
  366.         for j in range(M):
  367.             res[f][t+j] = Zxx[f][t+j]
  368.     return res
  369.  
  370.  
  371.  
  372. ## SIMULATION DE SALLE
  373.  
  374. pra.constants.set('c', 345)
  375.  
  376. fs, s1 = wavfile.read('/home/felix/Simulation salle/Test_salle_1m/ref_500Hz_pure.wav')
  377. fs, s2 = wavfile.read('/home/felix/Simulation salle/Test_salle_1m/ref_880Hz_pure.wav')
  378.  
  379. room_dim = [5, 5]
  380.  
  381. shoebox = pra.ShoeBox(
  382.     room_dim,
  383.     absorption=0.9999,
  384.     fs=fs,
  385.     max_order=0,
  386.     )
  387.  
  388. shoebox.add_source([2, 3.01], signal=s1)
  389. shoebox.add_source([2.02, 2.99], signal=s2)
  390.  
  391. R = np.array([[2,2.02],[3,3]])
  392. bf = pra.MicrophoneArray(R,shoebox.fs)
  393. shoebox.add_microphone_array(bf)
  394. shoebox.simulate()
  395.  
  396. shoebox.plot()
  397. plt.grid()
  398. plt.show()
  399.  
  400. audio_reverb = shoebox.mic_array.to_wav('/home/felix/test_reverb.wav', norm=True, bitdepth=np.int16)
  401.  
  402. ## Tests en salle
  403.  
  404. fs,m1 = wavfile.read('/home/felix/Simulation salle/Test LI-TIFROM retardé/Distance 0.5 bis/m-01.wav')
  405. fs, m2 = wavfile.read('/home/felix/Simulation salle/Test LI-TIFROM retardé/Distance 0.5 bis/m-02.wav')
  406.  
  407. def retarder(m1,n):
  408.     p = len(m1)
  409.     res = np.zeros(p+n)
  410.     for i in range(p):
  411.         res[n+i] = m1[i]
  412.     return res
  413.  
  414. def trouver_retard(m1,m2):
  415.     i = 0
  416.     cond = True
  417.     while cond:
  418.         if m1[i] == 0:
  419.             i = i +1
  420.         else:
  421.             cond = False
  422.    
  423.     j = 0
  424.     cond = True
  425.     while cond:
  426.         if m2[j] == 0:
  427.             j = j +1
  428.         else:
  429.             cond = False
  430.     return j - i,i,j
  431.  
  432.  
  433.  
  434. ## UN EXEMPLE
  435.  
  436. freq_echant, x1 = read("/home/felix/Simulation salle/Test_salle_0.1m/m-01.wav")
  437. freq_echant, x2 = read("/home/felix/Simulation salle/Test_salle_0.1m/m-02.wav")
  438. nb_echantillons = len(x1)
  439.  
  440. temps = np.linspace(0,nb_echantillons/freq_echant,nb_echantillons)
  441.  
  442. freq1,temps_seg1,Zxx_x1 = stft(x1,freq_echant,nperseg = 4000)
  443. freq2,temps_seg2,Zxx_x2 = stft(x2,freq_echant,nperseg = 4000)
  444. stft_x1 = np.abs(Zxx_x1)
  445. stft_x2 = np.abs(Zxx_x2)
  446. melanges_stft = np.array([np.abs(Zxx_x1),np.abs(Zxx_x2)])
  447. stft_melanges_comp = np.array([Zxx_x1,Zxx_x2])
  448. melanges = np.array([x1,x2])
  449.  
  450. rapp = rapport(melanges_stft[1],melanges_stft[0],freq_echant)
  451. var,nb_fenetre = variance(rapp,20)
  452.  
  453. var_trie = trier(var)
  454. visi,indmax,rappseul = detecter_sources_visibles(rapp,var_trie,5e-3,0.2,20,2)
  455. #rappseul[rappseul[:,2].argsort()]
  456.  
  457. L = visi[0]
  458. #L = visi[1]
  459.  
  460. Zxx_m1 = modifier_stft(Zxx_x1,L,20)
  461. tps1,res1 = istft(Zxx_m1,freq_echant,nperseg = 4000)
  462. write("/home/felix/1freq_m1.wav",freq_echant,res1)
  463.  
  464. Zxx_m2 = modifier_stft(Zxx_x2,L,20)
  465. tps2,res2 = istft(Zxx_m2,freq_echant,nperseg = 4000)
  466. write("/home/felix/1freq_m2.wav",freq_echant,res2)
  467.  
  468. def correlation(x,y,normalize):
  469.     xfft = np.fft.fft(x, 4*len(x))
  470.     yfft = np.fft.fft(y, 4*len(x))
  471.     R = xfft * np.conjugate(yfft)
  472.     if normalize:
  473.         R = R/np.abs(R)
  474.     c = np.fft.ifft(R)
  475.     return c
  476.  
  477. bruit = np.random.normal(0, 0.005, size=len(res1)+40)
  478.  
  479. res1_red = res1
  480. res2_red = res2
  481. xc = correlation(res1_red,res2_red,False)
  482. xc_phat = correlation(res1_red,res2_red,True)
  483.  
  484. abs = np.arange(-len(res1_red),len(res1_red),1)
  485.  
  486. bon1 = np.fft.fftshift(np.real(xc))[len(xc)//2 - len(res1_red):len(xc)//2 + len(res1_red)]
  487. bon2 = np.fft.fftshift(np.real(xc_phat))[len(xc)//2 - len(res1_red):len(xc)//2 + len(res1_red)]
  488. bon2[len(res1_red)] = 0
  489.  
  490. plt.subplot(2, 1, 1)
  491. plt.plot(abs, bon1)
  492. plt.title('A tale of 2 subplots')
  493. plt.xlim(xmax=100)  
  494. plt.xlim(xmin=-100)
  495. plt.grid()
  496.  
  497. plt.subplot(2, 1, 2)
  498. #plt.plot(abs, np.fft.fftshift(np.real(xc_phat)))
  499. plt.plot(abs, bon2)
  500. plt.xlim(xmax=100)  
  501. plt.xlim(xmin=-100)
  502.  
  503. plt.grid()
  504. plt.show()
  505.  
  506. mat_mixage = creer_mat_mixage(2,visi,rapp,20)
  507.  
  508. stft_res = np.zeros((2,len(freq1),len(temps_seg1)),dtype=complex)
  509. for fk in range(len(freq1)):
  510.     mat_mixage_inv = np.linalg.inv(np.array([[1,1],[mat_mixage[1][0]*np.exp(-1j*2*np.pi*(0)*freq1[fk]/freq_echant),mat_mixage[1][1]*np.exp(-1j*2*np.pi*(37)*freq1[fk]/freq_echant)]]))
  511.     L = np.dot(mat_mixage_inv,stft_melanges_comp[:,fk])
  512.     stft_res[0][fk] = L[0]
  513.     stft_res[1][fk] = L[1]
  514.  
  515.  
  516. tps1,res1 = istft(stft_res[0],freq_echant,nperseg = 4000)
  517. tps2,res2 = istft(stft_res[1],freq_echant,nperseg = 4000)
  518.  
  519. write("/home/felix/sourceseparee1_1m.wav",freq_echant,res1)
  520. write("/home/felix/sourceseparee2_1m.wav",freq_echant,res2)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement