ΡΠΈΡΡΠΎΠ²Π°Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΡΠΈΠ³Π½Π°Π»ΠΎΠ² Π½Π° Pyton. ΠΡΠΎΠ΅ΠΊΡ. ΠΠΎΠ±ΡΡΠΉ Π²Π΅ΡΠ΅Ρ! ΠΠ°ΠΏΠΈΡΠ°ΡΡ ΡΠ°Π±ΠΎΡΠΈΠΉ ΠΊΠΎΠ΄ Π½Π° Python ΠΈ ΠΎΠ±ΡΡΡΠ½ΠΈΡΡ Π΅Π³ΠΎ (ΠΆΠ΅Π»Π°ΡΠ΅Π»ΡΠ½ΠΎ Π² Jupyter Notebook + ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ .py-ΠΌΠΎΠ΄ΡΠ»ΠΈ) ΠΊΠΎΡΠΎΡΡΠΉ: β’ Π±Π΅ΡΡΡ ΡΠΈΡΡΡΠ΅ WAV-ΡΠ°ΠΉΠ»Ρ ΡΠ΅ΡΠΈ (16 ΠΊΠΡ) ΠΈ ΡΡΠΌΠ° ΡΠ°ΠΌΠΎΠ»ΡΡΠ°, β’ ΠΏΡΠΎΠΏΡΡΠΊΠ°Π΅Ρ ΡΠ΅ΡΡ ΡΠ΅ΡΠ΅Π· ΠΈΠΌΠΈΡΠ°ΡΠΈΡ Π°Π²ΠΈΠ°ΡΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΠΊΠ°Π½Π°Π»Π° (ΡΠ·ΠΊΠΎΠΏΠΎΠ»ΠΎΡΠ½ΡΠΉ ΡΠΈΠ»ΡΡΡ 300β3400 ΠΡ, ΡΠ΅ΡΡΠΌΠΏΠ» 8 ΠΊΠΡ) ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ ΡΡΠΌ ΠΏΡΠΈ SNR = 0/5/10 Π΄Π, β’ ΡΠ»ΡΡΡΠ°Π΅Ρ ΠΏΠΎΠ»ΡΡΠΈΠ²ΡΠΈΠΉΡΡ ΡΠΈΠ³Π½Π°Π»: ΠΏΡΠ΅Π΄ΡΡΠΊΠ°ΠΆΠ΅Π½ΠΈΠ΅ + ΡΠΊΠ²Π°Π»Π°ΠΉΠ·Π΅Ρ, ΡΠΏΠ΅ΠΊΡΡΠ°Π»ΡΠ½ΠΎΠ΅ Π²ΡΡΠΈΡΠ°Π½ΠΈΠ΅ (ΠΈΠ»ΠΈ Wiener), AGC. ΠΡΠΈΠΌΠ΅Ρ. GPT Π²ΡΠ΄Π°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°Π±ΠΎΡΠΈΠΉ ΠΊΠΎΠ΄, Π½ΠΎ Ρ Π½Π΅ ΡΠ°Π·Π±ΠΈΡΠ°ΡΡΡ Π² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ, ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ Π½Π΅ ΠΌΠΎΠ³Ρ β’ ΠΠΎΠ·ΡΠΌΡΠΌ ΡΠΈΡΡΡΠ΅ Π·Π°ΠΏΠΈΡΠΈ ΡΠ΅ΡΠΈ. β’ ΠΡΠΊΡΡΡΡΠ²Π΅Π½Π½ΠΎ Β«ΠΈΡΠΏΠΎΡΡΠΈΠΌΒ» ΠΈΡ
Π°Π²ΠΈΠ°ΡΠΈΠΎΠ½Π½ΡΠΌΠΈ ΡΡΠΌΠ°ΠΌΠΈ ΠΈ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π½ΠΎΠΉ ΠΏΠΎΠ»ΠΎΡΠΎΠΉ ΡΠ°ΡΡΠΎΡ β ΡΠ°ΠΊ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΠΈΠΌΠΈΡΠ°ΡΠΈΡ ΡΠ°Π΄ΠΈΠΎΠΊΠ°Π½Π°Π»Π°. β’ ΠΡΠΎΠ³ΠΎΠ½ΠΈΠΌ ΠΈΡΠΊΠ°ΠΆΡΠ½Π½ΡΠΉ ΡΠΈΠ³Π½Π°Π» ΡΠ΅ΡΠ΅Π· ΠΏΡΠΎΡΡΡΡ ΡΠ΅ΠΏΠΎΡΠΊΡ ΡΠΈΡΡΠΎΠ²ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ, ΡΡΠΎΠ±Ρ Π²Π΅ΡΠ½ΡΡΡ ΡΠ°Π·Π±ΠΎΡΡΠΈΠ²ΠΎΡΡΡ. β’ ΠΡΠΎΠ²Π΅ΡΠΈΠΌ, Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π»ΠΈ ΡΡΠ°Π»ΠΎ Π»ΡΡΡΠ΅ β ΡΠΈΡΡΠ°ΠΌΠΈ (SNR, STOI) ΠΈ ΠΆΠΈΠ²ΡΠΌΠΈ Π»ΡΠ΄ΡΠΌΠΈ. 2. Π§ΡΠΎ Π½ΡΠΆΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ 2.1 Π‘ΠΊΠ°ΡΠ°ΠΉΡΠ΅ ΠΈ ΠΏΠΎΡΡΠ°Π²ΡΡΠ΅ Β«Anaconda Individual EditionΒ» (ΡΠ°ΠΊ ΠΏΡΠΎΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ Python). 2.2 ΠΡΠΊΡΠΎΠΉΡΠ΅ Anaconda Prompt ΠΈ Π²Π²Π΅Π΄ΠΈΡΠ΅: conda create -n aviadsp python=3.10 conda activate aviadsp pip install numpy scipy librosa soundfile pystoi pypesq matplotlib tqdm ipywidgets 2.3 ΠΠΎΡΡΠ°Π²ΡΡΠ΅ Jupyter: pip install jupyterlab 3. Π‘ΠΎΠ·Π΄Π°ΡΠΌ ΡΠ°Π±ΠΎΡΡΡ ΠΏΠ°ΠΏΠΊΡ mkdir %USERPROFILE%\aviation_dsp cd %USERPROFILE%\aviation_dsp 4. Π‘ΠΊΠ°ΡΠΈΠ²Π°Π΅ΠΌ ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡΠ°Π²Π»ΠΈΠ²Π°Π΅ΠΌ Π΄Π°Π½Π½ΡΠ΅ 4.1 Π Π΅ΡΡ (ΠΊΠΎΡΠΏΡΡ CMU Arctic): wget https://festvox.org/cmu_arctic/cmu_us_bdl_arctic/packed/cmu_us_bdl_arctic-0.95-release.zip unzip cmu_us_bdl_arctic-0.95-release.zip 4.2 Π¨ΡΠΌΡ (ΠΏΡΠΈΠΌΠ΅Ρ: ΡΠ΅Π°ΠΊΡΠΈΠ²Π½ΡΠΉ Π΄Π²ΠΈΠ³Π°ΡΠ΅Π»Ρ): wget https://www.freesound.org/data/previews/91/91169_634166-lq.mp3 -O jet.mp3 ffmpeg -i jet.mp3 -ar 16000 -ac 1 jet.wav 4.3 ΠΡΠ±Π΅ΡΡΠΌ 75 ΡΠ»ΡΡΠ°ΠΉΠ½ΡΡ
ΡΡΠ°Π· ΠΈ ΠΎΠ±ΡΠ΅ΠΆΠ΅ΠΌ ΡΡΠΌ Π΄ΠΎ 3-4 ΠΌΠΈΠ½ΡΡ. Π‘Π°ΠΌΡΠΉ ΠΏΡΠΎΡΡΠΎΠΉ ΡΠΏΠΎΡΠΎΠ± β ΠΎΡΠΊΡΡΡΡ Jupyter ΠΈ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ: import glob, random, soundfile as sf, librosa, os, shutil, numpy as np, tqdm os.makedirs('clean', exist_ok=True) src = glob.glob('cmu_us_bdl_arctic/wav/*.wav') random.seed(0); random.shuffle(src) for f in src[:75]: shutil.copy(f, 'clean') noise, _ = librosa.load('jet.wav', sr=16000) sf.write('noise.wav', noise[:16000*180], 16000) 5. ΠΠΈΡΠ΅ΠΌ ΠΊΠΎΠ΄: ΠΈΠΌΠΈΡΠ°ΡΠΈΡ ΡΠ°Π΄ΠΈΠΎΠΊΠ°Π½Π°Π»Π° Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΡΠ°ΠΉΠ» channel.py: import numpy as np, scipy.signal as sg, librosa FS_IN, FS_CH = 16000, 8000 bp_taps = sg.firwin(255, [300, 3400], fs=FS_IN, pass_zero=False) def simulate(clean16, noise16, snr_db): # 1. ΠΠΎΡΡΠΎΠ²ΠΎΠΉ ΡΠΈΠ»ΡΡΡ + ΡΠ΅ΡΡΠΌΠΏΠ»ΠΈΠ½Π³ limited = sg.lfilter(bp_taps, 1, clean16) limited = sg.resample_poly(limited, FS_CH, FS_IN) # 2. Π£ΡΠ°Π²Π½ΡΠ΅ΠΌ ΡΡΠΎΠ²Π½ΠΈ RMS noise16 = noise16[:len(clean16)] limited_n = sg.lfilter(bp_taps, 1, noise16) noise8 = sg.resample_poly(limited_n, FS_CH, FS_IN) p_clean = np.mean(limited**2) p_noise = np.mean(noise8**2) k = np.sqrt(p_clean / (10**(snr_db/10)*p_noise)) noisy = limited + k*noise8 return noisy 6. ΠΠΈΡΠ΅ΠΌ ΠΊΠΎΠ΄: Π±Π»ΠΎΠΊ Β«ΡΠ»ΡΡΡΠ΅Π½ΠΈΡΒ» ΡΠ΅ΡΠΈ Π€Π°ΠΉΠ» enhance.py: import numpy as np, scipy.signal as sg FS = 8000 # 6.1 ΠΡΠ΅Π΄ΡΡΠΊΠ°ΠΆΠ΅Π½ΠΈΠ΅ + ΡΠΊΠ²Π°Π»ΠΈΠ·Π°ΡΠΈΡ pre_coef = 0.97 eq = sg.firwin2(129, [0,250,900,3000,3600,4000], [-6,-2,0,3,0,-12], fs=FS) # 6.2 Π‘ΠΏΠ΅ΠΊΡΡΠ°Π»ΡΠ½ΠΎΠ΅ Π²ΡΡΠΈΡΠ°Π½ΠΈΠ΅ def spectral_sub(y, n_fft=256): f,t,Z = sg.stft(y, FS, nperseg=n_fft, noverlap=n_fft//2) mag, ph = np.abs(Z), np.angle(Z) noise = np.mean(mag[:,:10], axis=1, keepdims=True) mag_hat = np.maximum(mag - 2.5*noise, 0.01*noise) Z_hat = mag_hat*np.exp(1j*ph) _, x = sg.istft(Z_hat, FS, nperseg=n_fft, noverlap=n_fft//2) return x # 6.3 AGC def agc(x, target=-22, gmax=12): win = int(0.04*FS) level = np.sqrt(sg.convolve(x**2, np.ones(win)/win,'same')) gain = np.clip(10**((target - 20*np.log10(level+1e-6))/20), 10**(-gmax/20), 10**(gmax/20)) return x*gain def enhance(y): y1 = sg.lfilter([1,-pre_coef],1,y) # ΠΏΡΠ΅Π΄ΡΡΠΊΠ°ΠΆΠ΅Π½ΠΈΠ΅ y2 = sg.lfilter(eq,1,y1) # ΡΠΊΠ²Π°Π»Π°ΠΉΠ·Π΅Ρ y3 = spectral_sub(y2) # ΡΡΠΌΠΎΠΏΠΎΠ΄Π°Π²Π»Π΅Π½ΠΈΠ΅ y4 = agc(y3) # Π²ΡΡΠ°Π²Π½ΠΈΠ²Π°Π½ΠΈΠ΅ Π³ΡΠΎΠΌΠΊΠΎΡΡΠΈ return np.clip(y4, -1, 1) 7. ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ ΡΠ΅ΠΏΠΎΡΠΊΡ Π½Π° ΠΎΠ΄Π½ΠΎΠΉ ΡΡΠ°Π·Π΅ import soundfile as sf, numpy as np, librosa, channel, enhance clean, _ = librosa.load('clean/arctic_a0001.wav', sr=16000) noise, _ = librosa.load('noise.wav', sr=16000) noisy = channel.simulate(clean, noise, snr_db=0) proc = enhance.enhance(noisy) sf.write('noisy.wav', noisy, 8000) sf.write('proc.wav', proc, 8000) print('done β ΡΠ»ΡΡΠ°ΠΉΡΠ΅ noisy.wav ΠΈ proc.wav')...