Advertisement
juanmartinvk

gen_frd

May 31st, 2020
1,120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.00 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2.  
  3. import numpy as np
  4. import soundfile as sf
  5. import os
  6.  
  7. # =============================================================================
  8. # Código para generar y guardar archivos FRD a partir de respuestas al impulso
  9. # en formato .wav.
  10. # =============================================================================
  11.  
  12.  
  13. #Tamaño de la FFT
  14. fft_size= 16384
  15. #Samples de start y stop
  16. start_sample = 48000
  17. stop_sample = 48120
  18.  
  19.  
  20. #Calibración con señal de 94 dBSPL
  21. cal_enable = True
  22. cal_SPL = 94
  23. cal_file = "../Cal/signal.wav" #Ruta del archivo de calibración
  24.  
  25. save_dir = "../Mediciones/H/"  #Ruta del directorio destino
  26. file_extension = ".frd"        #Extensión del archivo (ej ".frd", ".txt")
  27.  
  28.  
  29.  
  30.  
  31.  
  32. def ir_to_frd(archivo):
  33. # =============================================================================
  34. # Recibe una IR en .wav y devuelve un array formato FRD (columnas f, mag, phase)
  35. # Se debe especificar las muestras de start y stop y el tamaño de la FFT
  36. # =============================================================================
  37.     #Lee el wav
  38.     wav, fs = sf.read(archivo)
  39.     #Ventanea
  40.     amp = wav[start_sample:stop_sample]
  41.     #Crea un array de frecuencias
  42.     frecuencias = np.linspace(0, fs/2, fft_size//2)
  43.     #Calibración a SPL
  44.     if cal_enable == True:
  45.         amp = calibrate(amp)
  46.     #FFT
  47.     spectrum = np.fft.fft(amp, fft_size)
  48.     mag = np.abs(spectrum[0:fft_size//2])
  49.     phase = np.angle(spectrum[0:fft_size//2], deg=True)
  50.     #dB
  51.     mag = 20*np.log10(mag)
  52.    
  53.     #Averigua el índice de la primera frecuencia superior a 20 Hz
  54.     for i, f in enumerate(frecuencias):
  55.         if f-20 >= 0:
  56.             idx_20 = i
  57.             break
  58.     #Hace que todo arranque de 20 Hz
  59.     frecuencias = frecuencias[idx_20:]
  60.     mag = mag[idx_20:]
  61.     phase = phase[idx_20:]
  62.    
  63.     #Stackea frecuencias, mag, phase
  64.     frd = np.vstack((frecuencias, mag, phase))
  65.    
  66.     #Transpone para que queden en columnas en vez de filas
  67.     frd = np.transpose(frd)
  68.    
  69.     return frd
  70.  
  71.  
  72.  
  73. def calibrate(amp):
  74. # =============================================================================
  75. # Recibe un array de amplitudes y calibra la amplitud respecto del valor RMS de
  76. # una señal de calibración (normalmente a 94dBSPL).
  77. # =============================================================================
  78.     #Lee el archivo de calibración
  79.     cal, fs = sf.read(cal_file)
  80.     #Saca el valor RMS
  81.     cal_rms = np.sqrt(np.mean(cal**2))
  82.     #Saca la relación de presiones y le suma 94 dB
  83.     ampcal = amp/cal_rms * 10**(cal_SPL/20)
  84.     return ampcal
  85.  
  86.  
  87.  
  88.  
  89.  
  90. #Cambia al directorio destino
  91. os.chdir(save_dir)
  92.  
  93. #Crea una lista de archivos (creala como sea más conveniente)
  94. archivos=[]
  95. for i in range(37):
  96.     archivos.append("{} grados_hor.wav".format(i*5-90))
  97.  
  98. # Para cada archivo saca la FRD y lo guarda en un archivo con la extensión
  99. # seleccionada. También, iterar como sea más conveniente.
  100. for i, archivo in enumerate(archivos):
  101.     frd = ir_to_frd(archivo)
  102.     np.savetxt("hor_deg{}".format(i*5-90)+file_extension, frd, fmt='%1.3f')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement