diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 628b2844..d12e0b8c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,11 @@ lib_mic_array change log ======================== +5.2.0 +----- + + * Added 48 kHz decimator design script + 5.1.0 ----- diff --git a/lib_mic_array/module_build_info b/lib_mic_array/module_build_info index 11b769a3..7d371ccf 100644 --- a/lib_mic_array/module_build_info +++ b/lib_mic_array/module_build_info @@ -1,4 +1,4 @@ -VERSION = 5.0.3 +VERSION = 5.2.0 DEPENDENT_MODULES = lib_xcore_math diff --git a/script/filter_design/design_filter.py b/script/filter_design/design_filter.py index 0050f7b0..2e8e2cfa 100644 --- a/script/filter_design/design_filter.py +++ b/script/filter_design/design_filter.py @@ -320,6 +320,44 @@ def good_32k_filter(int_coeffs: bool): return coeffs +def good_48k_filter(int_coeffs: bool): + fs_0 = 3072000 + decimations = [32, 2] + + # stage 1 parameters + ma_stages = 5 + + # stage 2 parameters + cutoff = 20000 + transition_bandwidth = 1000 + taps_2 = 96 + fir_window = ("kaiser", 6.5) + stage_2 = stage_params(cutoff, transition_bandwidth, taps_2, fir_window) + + coeffs = design_2_stage(fs_0, decimations, ma_stages, stage_2, int_coeffs=int_coeffs) + + return coeffs + + +def small_48k_filter(int_coeffs: bool): + fs_0 = 3072000 + decimations = [32, 2] + + # stage 1 parameters + ma_stages = 5 + + # stage 2 parameters + cutoff = 20000 + transition_bandwidth = 1000 + taps_2 = 64 + fir_window = ("kaiser", 8) + stage_2 = stage_params(cutoff, transition_bandwidth, taps_2, fir_window) + + coeffs = design_2_stage(fs_0, decimations, ma_stages, stage_2, int_coeffs=int_coeffs) + + return coeffs + + def main(): coeffs = small_2_stage_filter(int_coeffs=True) out_path = "small_2_stage_filter_int.pkl" @@ -333,10 +371,20 @@ def main(): out_path = "good_3_stage_filter_int.pkl" ft.save_packed_filter(out_path, coeffs) + # For more info on 32kHz and 48kHz design, see + # https://xmosjira.atlassian.net/wiki/spaces/CONF/pages/3805052950/32k+and+48k+Hz+lib+mic+array + coeffs = good_32k_filter(int_coeffs=True) out_path = "good_32k_filter_int.pkl" ft.save_packed_filter(out_path, coeffs) + coeffs = good_48k_filter(int_coeffs=True) + out_path = "good_48k_filter_int.pkl" + ft.save_packed_filter(out_path, coeffs) + + coeffs = small_48k_filter(int_coeffs=True) + out_path = "small_48k_filter_int.pkl" + ft.save_packed_filter(out_path, coeffs) if __name__ == "__main__": main() diff --git a/script/filter_design/filter_tools.py b/script/filter_design/filter_tools.py index b8d3b579..58396887 100644 --- a/script/filter_design/filter_tools.py +++ b/script/filter_design/filter_tools.py @@ -87,8 +87,16 @@ def moving_average_filter_int16(decimation_ratio, n_stages, optimise_scaling=Tru # with the next stage. Use a 2 stage MA again for the final convolution rounding_stages = n_stages - 3 if n_stages > 5: - # rounding could add up to len(b) to the value, compensate scaling - max_value = (32767.0 - len(b)*rounding_stages) + # rounding could add up to len(b) to the value, compensate scaling, + # not all values have been tested, so some may fail + if n_stages in [5]: + max_value = (32767.0 - len(b)) + elif n_stages in [7, 8]: + # hand tuned to get lucky on the rounding, there's probably a nicer way + max_value = (32767.0 - 7*len(b)) + else: + # sometimes adds up to more than len(b), add extra to be safe + max_value = (32767.0 - len(b)*n_stages) else: max_value = 32767.0 scaling = np.max(b)/max_value