@@ -79,6 +79,10 @@ def generate_integrated_brir(brir_name, spatial_res=1, report_progress=0, gui_l
7979 hrtf_direction_misalign_comp = brir_meta_dict .get ("hrtf_direction_misalign_comp" )
8080 hrtf_df_cal_mode = brir_meta_dict .get ("hrtf_df_cal_mode" )
8181 reverb_tail_crop_db = brir_meta_dict .get ("reverb_tail_crop_db" )
82+ brir_df_cal_mode = brir_meta_dict .get ("brir_df_cal_mode" )
83+ brir_max_length = brir_meta_dict .get ("brir_max_length" )
84+ octave_smoothing_n = brir_meta_dict .get ("octave_smoothing_n" )
85+ brir_df_cal_factor = brir_meta_dict .get ("brir_df_cal_factor" )
8286 else :
8387 raise ValueError ('brir_meta_dict not populated' )
8488
@@ -215,6 +219,12 @@ def generate_integrated_brir(brir_name, spatial_res=1, report_progress=0, gui_l
215219 needs_update = True
216220
217221 if needs_update :
222+ log_string = 'Downloading updates'
223+ hf .log_with_timestamp (log_string , gui_logger )
224+ if report_progress > 0 :
225+ progress = 1 / 100
226+ hf .update_gui_progress (report_progress = report_progress , progress = progress , message = log_string )
227+
218228 air_processing .acoustic_space_updates (download_updates = True , gui_logger = gui_logger )
219229 except Exception as e :
220230 hf .log_with_timestamp (f"Failed to check/update acoustic spaces: { e } " , gui_logger )
@@ -347,9 +357,7 @@ def generate_integrated_brir(brir_name, spatial_res=1, report_progress=0, gui_l
347357 total_azim_hrir = len (hrir_selected [0 ])
348358 total_chan_hrir = len (hrir_selected [0 ][0 ])
349359 total_samples_hrir = len (hrir_selected [0 ][0 ][0 ])
350- base_elev_idx = total_elev_hrir // 2
351-
352-
360+
353361 ############################## DF calibration CTF loading
354362 #
355363 ctf_mag_db = None # main CTF magnitude in dB
@@ -538,50 +546,51 @@ def generate_integrated_brir(brir_name, spatial_res=1, report_progress=0, gui_l
538546
539547
540548 # grab reverberant BRIRs from interim matrix and place in output matrix
541- for elev in range (total_elev_hrir ):
542- for azim in range (total_azim_hrir ):
543- azim_deg = int (azim * azim_nearest )
544- #case for minimal set (7 directions)
545- if total_azim_reverb == 7 :
546- if azim_deg < 15 or azim_deg > 345 :
547- brir_azim_ind = 0
548- elif azim_deg < 60 :
549- brir_azim_ind = 1
550- elif azim_deg < 120 :
551- brir_azim_ind = 2
552- elif azim_deg < 180 :
553- brir_azim_ind = 3
554- elif azim_deg <= 240 :
555- brir_azim_ind = 4
556- elif azim_deg <= 300 :
557- brir_azim_ind = 5
558- else :
559- brir_azim_ind = 6
560- #case for minimal set (5 directions)
561- elif total_azim_reverb == 5 :
562- if azim_deg < 15 or azim_deg > 345 :
563- brir_azim_ind = 0
564- elif azim_deg < 120 :
565- brir_azim_ind = 1
566- elif azim_deg < 180 :
567- brir_azim_ind = 2
568- elif azim_deg <= 240 :
569- brir_azim_ind = 3
549+ if meas_rt60 > 0 :
550+ for elev in range (total_elev_hrir ):
551+ for azim in range (total_azim_hrir ):
552+ azim_deg = int (azim * azim_nearest )
553+ #case for minimal set (7 directions)
554+ if total_azim_reverb == 7 :
555+ if azim_deg < 15 or azim_deg > 345 :
556+ brir_azim_ind = 0
557+ elif azim_deg < 60 :
558+ brir_azim_ind = 1
559+ elif azim_deg < 120 :
560+ brir_azim_ind = 2
561+ elif azim_deg < 180 :
562+ brir_azim_ind = 3
563+ elif azim_deg <= 240 :
564+ brir_azim_ind = 4
565+ elif azim_deg <= 300 :
566+ brir_azim_ind = 5
567+ else :
568+ brir_azim_ind = 6
569+ #case for minimal set (5 directions)
570+ elif total_azim_reverb == 5 :
571+ if azim_deg < 15 or azim_deg > 345 :
572+ brir_azim_ind = 0
573+ elif azim_deg < 120 :
574+ brir_azim_ind = 1
575+ elif azim_deg < 180 :
576+ brir_azim_ind = 2
577+ elif azim_deg <= 240 :
578+ brir_azim_ind = 3
579+ else :
580+ brir_azim_ind = 4
581+ #case for multiple directions on horizontal plane, every x deg azimuth
582+ elif total_azim_reverb > 0 :
583+ #map hrir azimuth to appropriate brir azimuth
584+ #round azim to nearest X deg and get new ID
585+ brir_azim = hf .round_to_multiple (azim_deg ,nearest_azim_reverb )#brir_reverberation is nearest X deg, variable
586+ if brir_azim >= 360 :
587+ brir_azim = 0
588+ brir_azim_ind = int (brir_azim / nearest_azim_reverb )#get index
570589 else :
571- brir_azim_ind = 4
572- #case for multiple directions on horizontal plane, every x deg azimuth
573- elif total_azim_reverb > 0 :
574- #map hrir azimuth to appropriate brir azimuth
575- #round azim to nearest X deg and get new ID
576- brir_azim = hf .round_to_multiple (azim_deg ,nearest_azim_reverb )#brir_reverberation is nearest X deg, variable
577- if brir_azim >= 360 :
578- brir_azim = 0
579- brir_azim_ind = int (brir_azim / nearest_azim_reverb )#get index
580- else :
581- raise ValueError ('Unable to process BRIR reverberation data. Invalid number of reverberation sources: ' + str (total_azim_reverb ) )
582-
583- for chan in range (CN .TOTAL_CHAN_BRIR ):
584- brir_out [elev ][azim ][chan ][0 :n_fft ] = np .copy (brir_reverberation [0 ][brir_azim_ind ][chan ][0 :n_fft ])
590+ raise ValueError ('Unable to process BRIR reverberation data. Invalid number of reverberation sources: ' + str (total_azim_reverb ) )
591+
592+ for chan in range (CN .TOTAL_CHAN_BRIR ):
593+ brir_out [elev ][azim ][chan ][0 :n_fft ] = np .copy (brir_reverberation [0 ][brir_azim_ind ][chan ][0 :n_fft ])
585594
586595
587596
@@ -709,9 +718,9 @@ def generate_integrated_brir(brir_name, spatial_res=1, report_progress=0, gui_l
709718 #convert to mag
710719 brir_fft_avg_mag = hf .db2mag (brir_fft_avg_db )
711720 #level ends of spectrum
712- brir_fft_avg_mag_sm = hf .level_spectrum_ends (brir_fft_avg_mag , 15 , 18500 , smooth_win = 5 , n_fft = CN .N_FFT )#40, 19000, smooth_win = 7
721+ brir_fft_avg_mag_sm = hf .level_spectrum_ends (brir_fft_avg_mag , 15 , 18500 , smooth_win = octave_smoothing_n , n_fft = CN .N_FFT )#40, 19000, smooth_win = 7
713722 #octave smoothing
714- brir_fft_avg_mag_sm = hf .smooth_gaussian_octave (data = brir_fft_avg_mag_sm , n_fft = CN .N_FFT , fraction = 6 )
723+ brir_fft_avg_mag_sm = hf .smooth_gaussian_octave (data = brir_fft_avg_mag_sm , n_fft = CN .N_FFT , fraction = octave_smoothing_n )
715724
716725 #include CTF if DF calibration reversal is enabled
717726 if ctf_adj_loaded and ctf_adj_mag_db is not None :
@@ -720,8 +729,9 @@ def generate_integrated_brir(brir_name, spatial_res=1, report_progress=0, gui_l
720729 hf .log_with_timestamp ("HRTF CTF Adjustment response available, applying to integrated response CTF." )
721730
722731
723- #invert response
724- brir_fft_avg_mag_inv = hf .db2mag (hf .mag2db (brir_fft_avg_mag_sm )* - 1 )
732+ #invert response and scale by user selected strength factor
733+ brir_df_cal_factor = max (0.05 ,brir_df_cal_factor )
734+ brir_fft_avg_mag_inv = hf .db2mag (hf .mag2db (brir_fft_avg_mag_sm )* - 1 * brir_df_cal_factor )
725735
726736 #include CTF if DF calibration reversal is enabled
727737 if df_cal_reversal :
@@ -732,7 +742,19 @@ def generate_integrated_brir(brir_name, spatial_res=1, report_progress=0, gui_l
732742 hf .log_with_timestamp ("HRTF CTF DF response not available, skipping HRTF DF reintegration." , gui_logger )
733743
734744 #create min phase FIR
735- brir_df_inv_fir = hf .build_min_phase_filter (smoothed_mag = brir_fft_avg_mag_inv , truncate_len = 4096 , n_fft = CN .N_FFT )#2048
745+ if brir_df_cal_mode == CN .BRIR_DF_CAL_MODE_LIST [0 ]:
746+ brir_df_inv_fir = hf .build_min_phase_filter (smoothed_mag = brir_fft_avg_mag_inv , truncate_len = 4096 , n_fft = CN .N_FFT )
747+ elif brir_df_cal_mode == CN .BRIR_DF_CAL_MODE_LIST [1 ]:
748+ # 1. Define your impulse (e.g., 8192 samples long)
749+ n_fft_param = 8192
750+ impulse = np .zeros ((1 , 1 , n_fft_param ))
751+ impulse [0 , 0 , 0 ] = 1.0 # Set the first sample to 1.0
752+ # 2. Run your function with the override
753+ # This will return the EQ-IR as a (1, 1, n_fft) array
754+ eq_ir_dataset = hf .equalize_brirs_parametric (brir_dataset = impulse , diff_db_override = hf .mag2db (brir_fft_avg_mag_inv ), override_n_fft = CN .N_FFT ,
755+ num_filters = 50 ,low_freq_cut = 12.0 , high_freq_cut = 18000.0 )
756+ # 3. Extract the 1D array for easy convolution later
757+ brir_df_inv_fir = eq_ir_dataset .flatten ()
736758
737759 if report_progress > 0 :
738760 progress = 80 / 100
@@ -751,7 +773,9 @@ def generate_integrated_brir(brir_name, spatial_res=1, report_progress=0, gui_l
751773 #larger reverb times will need additional samples
752774 #estimate output array length based on RT60
753775 #Below determines the most samples to keep based on estimated rt60
754- if meas_rt60 <= 400 :
776+ if meas_rt60 <= 0 :
777+ out_samples_max = 512
778+ elif meas_rt60 <= 400 :
755779 out_samples_max = 33075
756780 elif meas_rt60 <= 1250 :
757781 out_samples_max = 64500
@@ -768,6 +792,8 @@ def generate_integrated_brir(brir_name, spatial_res=1, report_progress=0, gui_l
768792 crop_samples = hf .get_crop_index_relative (ref_array , tail_ignore = 8000 ,head_ignore = 100 , threshold_db = reverb_tail_crop_db ) #crop_samples = hf.get_crop_index(ref_array, tail_ignore=10000)
769793 if crop_samples < 2000 or crop_samples > out_samples_max :#ensure it stays within limits. Not suitable for short IRs (<50ms)
770794 crop_samples = out_samples_max
795+ if crop_samples > brir_max_length :#clamp to user specified max length
796+ crop_samples = brir_max_length
771797
772798 #merge filters into single EQ filter
773799 eq_filter = brir_df_inv_fir
@@ -1157,7 +1183,10 @@ def apply_peaking_filters(filter_seq, impulse, samp_freq):
11571183 {'fc' : 10500 , 'q' : 5.0 , 'gain_db' : - 3.0 }],
11581184 'd' : [{'fc' : 3000 , 'q' : 2.0 , 'gain_db' : - 6.0 }, {'fc' : 1500 , 'q' : 3.0 , 'gain_db' : 1.5 }, {'fc' : 5900 , 'q' : 3.0 , 'gain_db' : 3.5 },
11591185 {'fc' : 4500 , 'q' : 3.0 , 'gain_db' : 2.5 }, {'fc' : 9500 , 'q' : 7.0 , 'gain_db' : - 4.0 }, {'fc' : 3600 , 'q' : 5.0 , 'gain_db' : - 2.0 },
1160- {'fc' : 10800 , 'q' : 4.0 , 'gain_db' : - 2.0 }, {'fc' : 7700 , 'q' : 7.0 , 'gain_db' : 2.0 }, {'fc' : 6300 , 'q' : 7.0 , 'gain_db' : 1.0 }]
1186+ {'fc' : 10800 , 'q' : 4.0 , 'gain_db' : - 2.0 }, {'fc' : 7700 , 'q' : 7.0 , 'gain_db' : 2.0 }, {'fc' : 6300 , 'q' : 7.0 , 'gain_db' : 1.0 }],
1187+ 'e' : [{'fc' : 1400 , 'q' : 2.5 , 'gain_db' : 1.0 }, {'fc' : 2100 , 'q' : 4.0 , 'gain_db' : - 2.5 }, {'fc' : 2800 , 'q' : 2.5 , 'gain_db' : - 3.0 },
1188+ {'fc' : 4500 , 'q' : 4.0 , 'gain_db' : - 3.0 }, {'fc' : 5900 , 'q' : 2.0 , 'gain_db' : 1.0 }, {'fc' : 6600 , 'q' : 8.0 , 'gain_db' : - 1.5 },
1189+ {'fc' : 7200 , 'q' : 4.0 , 'gain_db' : 4.0 }, {'fc' : 8200 , 'q' : 4.0 , 'gain_db' : 2.0 }, {'fc' : 10100 , 'q' : 9.0 , 'gain_db' : - 7.0 }, {'fc' : 11000 , 'q' : 7.0 , 'gain_db' : - 5.0 }]
11611190 }
11621191
11631192 oe_hs_comp_mag = {}
@@ -1169,20 +1198,24 @@ def apply_peaking_filters(filter_seq, impulse, samp_freq):
11691198 hf .plot_data (np .abs (data_fft ), f'oe_hs_comp_{ key } _mag' , normalise = 1 )
11701199
11711200 # Weighted average of HS comp a/b/c
1172- oe_hs_comp_avg_db = np .sum ([oe_hs_comp_mag [k ]* w for k , w in zip (['a' ,'b' ,'c' ,'d' ], [0.25 ,0.15 ,0.15 ,0.45 ])], axis = 0 ) * - 1 #0.4,0.3,0.3
1173- oe_hs_new_avg_db = np .sum ([oe_hs_comp_avg_db * 0.6 , hf .mag2db (over_ear_add_eq_mag )* 0.4 ], axis = 0 )
1201+ oe_hs_comp_avg_db = np .sum ([oe_hs_comp_mag [k ]* w for k , w in zip (['a' ,'b' ,'c' ,'d' , 'e' ], [0.17 ,0.17 ,0.17 ,0.29 , 0.20 ])], axis = 0 ) * - 1 #0.4,0.3,0.3 - 0.25,0.15,0.15,0.45
1202+ oe_hs_new_avg_db = np .sum ([oe_hs_comp_avg_db * 0.70 , hf .mag2db (over_ear_add_eq_mag )* 0.30 ], axis = 0 )
11741203
11751204 # --- Final over-ear curves ---
11761205 over_ear_high_db = hf .mag2db (hp_est_avg_mag ) + oe_hs_new_avg_db
11771206
11781207 if CN .PLOT_ENABLE :
1208+ oe_hs_comp_avg_mag = hf .db2mag (oe_hs_comp_avg_db )
11791209 oe_hs_new_avg_mag = hf .db2mag (oe_hs_new_avg_db )
11801210 oe_hs_new_avg_mag_inv = hf .db2mag (oe_hs_new_avg_db * - 1 )
11811211 over_ear_high_mag = hf .db2mag (over_ear_high_db )
11821212 in_ear_high_mag = hf .db2mag (in_ear_high_db )
11831213 in_ear_low_mag = hf .db2mag (in_ear_low_db )
1214+
11841215 hf .plot_data (hp_est_avg_mag , 'hp_est_avg_mag (Over ear HP Ear interactions, low strength)' , normalise = 1 )
1185- hf .plot_data (oe_hs_new_avg_mag , 'oe_hs_new_avg_mag (Over ear additional interactions)' , normalise = 1 )
1216+ hf .plot_data (over_ear_add_eq_mag , 'over_ear_add_eq_mag (Over ear additional interactions v1)' , normalise = 1 )
1217+ hf .plot_data (oe_hs_comp_avg_mag , 'oe_hs_comp_avg_mag (Over ear additional interactions v2)' , normalise = 1 )
1218+ hf .plot_data (oe_hs_new_avg_mag , 'oe_hs_new_avg_mag (Over ear additional interactions v3 avg)' , normalise = 1 )
11861219 hf .plot_data (oe_hs_new_avg_mag_inv , 'oe_hs_new_avg_mag_inv (Over ear additional interactions inverted)' , normalise = 1 )
11871220 hf .plot_data (over_ear_high_mag , 'over_ear_high_mag (Over ear HP Ear interactions, high strength)' , normalise = 1 )
11881221 hf .plot_data (in_ear_low_mag , 'in_ear_high_mag (In ear HP Ear interactions, low strength)' , normalise = 1 )
0 commit comments