Scripts#
stage1.py and stage2.py#
These scripts can be used to generate C code representing the required first and second stage filters used by the mic array.
stage1.pyoutputs an array for the first stage filterstage2.pyoutputs an array for the second stage filter
Each script takes a Python .pkl file as an input (via the command line), and
outputs a simple C-style array initializer in the terminal. That output can be
used to overwrite the filter coefficients in an application.
Example#
The following is an example of running stage1.py.
lib_mic_array\python>python stage1.py filter_design\good_2_stage_filter_int.pkl
Stage 1 Decimation Factor: 32
Stage 1 Tap Count: 125
Stage 2 Decimation Factor: 6
Stage 2 Tap Count: 256
Filter word count: 128
{
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xEEEEEEEE, 0xEEEEEEEE, 0xEEEEEEEE, 0xEEEEEEEE,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFAFAFAFA, 0xFAFAFAFA, 0xEBEBEBEB, 0xEBEBEBEB,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xF5A0F5A0, 0xE4B1E4B1, 0xF1A4F1A4, 0xE0B5E0B5,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFB51AE04, 0xEF54BA01, 0xF00BA55E, 0xE40EB15B,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFD1353BD, 0xB31809B3, 0xF9B20319, 0xB7B95917,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFE4D120F, 0x584AEB52, 0xA95AEA43, 0x5E09164F,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF94E621, 0x17931C80, 0x0027193D, 0x108CE53F,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFE6AE34, 0xE549505E, 0xEF415254, 0xE58EACFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFF8CB6C, 0x066D9FCB, 0x1A7F36CC, 0x06DA63FF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFF0C49, 0x52DB4A93, 0xF92A5B69, 0x52461FFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF071, 0x9B6D931C, 0x071936DB, 0x31C1FFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFF81, 0xE38E1C1F, 0xFF070E38, 0xF03FFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x03F01FE0, 0x00FF01F8, 0x0FFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFC001FFF, 0xFFFF0007, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE000, 0x0000FFFF, 0xFFFFFFFF,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
}
Here, the input .pkl file good_2_stage_filter_int.pkl was generated
using filter_design/design_filter.py. The script outputs some basic
information about the filter followed by a C array initializer of 128 words.
The output array can be used to initialize an array of type uint32_t. The
values in the array may appear to have little relation to those directly in the
.pkl file because the implementation of the first stage filter requires the
coefficients to be reordered in a bit-wise manner for run-time optimization.
The following is an example of stage2.py being run with the same input file.
lib_mic_array\python>python stage2.py filter_design\good_2_stage_filter_int.pkl
Stage 1 Decimation Factor: 32
Stage 1 Tap Count: 125
Stage 2 Decimation Factor: 6
Stage 2 Tap Count: 256
Right-shift: 4
{
0x12cbd, 0x1bc68, 0x1e848, 0x16e3b, 0x34fc, -0x19c13, -0x396a4, -0x517d3, -0x572c4, -0x42a99, -0x12b2d, 0x3136a, 0x78fc9, 0xaf0c5, 0xbdfb3, 0x976fb, 0x3a55b, -0x49c82, -0xd5ee1, -0x141f1d, -0x166e07, -0x12b197, -0x8cb56, 0x594d5, 0x151a2b, 0x217aba, 0x268fd9, 0x219572, 0x123738, -0x4ec96, -0x1e8a6b, -0x33c24b, -0x3ddb52, -0x383953, -0x220324, 0x10d0c, 0x290b3c, 0x4b7d38, 0x5df58f, 0x590923, 0x3ad314, 0x83f9d, -0x336a4b, -0x68da62, -0x887959, -0x86bb28, -0x5fdb9e, -0x19e511, 0x3bc670, 0x8b8db4, 0xbedc73, 0xc4446c, 0x94e8ba, 0x379c2f, -0x3f6e52, -0xb2ae73, -0x10257a9, -0x114d20e, -0xde6ae6, -0x66087d, 0x3abb9a, 0xdc9726, 0x153d6f5, 0x17bd0e7, 0x141966a, 0xaae708, -0x28e308, -0x106c5f0, -0x1b3f8e6, -0x1fd12db, -0x1c4a9b6, -0x10d64a6, 0x3a8af, 0x12db80b, 0x2232795, 0x29d2c56, 0x26f81a8, 0x196c603, 0x3d29f5, -0x14cb2a5, -0x2a1db99, -0x3623ba6, -0x34cc828, -0x253b843, -0xa4d6a3, 0x15d59b2, 0x33128a8, 0x45581b2, 0x46c6158, 0x357091a, 0x143e5e3, -0x156ca08, -0x3d3d9c1, -0x586bd77, -0x5e8a05f, -0x4bf99e5, -0x235288f, 0x12b764c, 0x490cfd8, 0x713c998, 0x7f2705a, 0x6c6a6e1, 0x3aa1c29, -0xc38997, -0x578b750, -0x93c3c2b, -0xaf1da5a, -0x9e75bfb, -0x60eaa5b, -0x14591a, 0x6b69c4c, 0xc9ef41c, 0xff16c12, 0xf689a74, 0xa8d3041, 0x1f08228, -0x8cffe95, -0x13445d3b, -0x1a994e72, -0x1c28c7ca, -0x160ef96b, -0x7a3c5f0, 0xe431389, 0x295878fd, 0x4629d110, 0x60af1114, 0x74fe4fe9, 0x7fffffff, 0x7fffffff, 0x74fe4fe9, 0x60af1114, 0x4629d110, 0x295878fd, 0xe431389, -0x7a3c5f0, -0x160ef96b, -0x1c28c7ca, -0x1a994e72, -0x13445d3b, -0x8cffe95, 0x1f08228, 0xa8d3041, 0xf689a74, 0xff16c12, 0xc9ef41c, 0x6b69c4c, -0x14591a, -0x60eaa5b, -0x9e75bfb, -0xaf1da5a, -0x93c3c2b, -0x578b750, -0xc38997, 0x3aa1c29, 0x6c6a6e1, 0x7f2705a, 0x713c998, 0x490cfd8, 0x12b764c, -0x235288f, -0x4bf99e5, -0x5e8a05f, -0x586bd77, -0x3d3d9c1, -0x156ca08, 0x143e5e3, 0x357091a, 0x46c6158, 0x45581b2, 0x33128a8, 0x15d59b2, -0xa4d6a3, -0x253b843, -0x34cc828, -0x3623ba6, -0x2a1db99, -0x14cb2a5, 0x3d29f5, 0x196c603, 0x26f81a8, 0x29d2c56, 0x2232795, 0x12db80b, 0x3a8af, -0x10d64a6, -0x1c4a9b6, -0x1fd12db, -0x1b3f8e6, -0x106c5f0, -0x28e308, 0xaae708, 0x141966a, 0x17bd0e7, 0x153d6f5, 0xdc9726, 0x3abb9a, -0x66087d, -0xde6ae6, -0x114d20e, -0x10257a9, -0xb2ae73, -0x3f6e52, 0x379c2f, 0x94e8ba, 0xc4446c, 0xbedc73, 0x8b8db4, 0x3bc670, -0x19e511, -0x5fdb9e, -0x86bb28, -0x887959, -0x68da62, -0x336a4b, 0x83f9d, 0x3ad314, 0x590923, 0x5df58f, 0x4b7d38, 0x290b3c, 0x10d0c, -0x220324, -0x383953, -0x3ddb52, -0x33c24b, -0x1e8a6b, -0x4ec96, 0x123738, 0x219572, 0x268fd9, 0x217aba, 0x151a2b, 0x594d5, -0x8cb56, -0x12b197, -0x166e07, -0x141f1d, -0xd5ee1, -0x49c82, 0x3a55b, 0x976fb, 0xbdfb3, 0xaf0c5, 0x78fc9, 0x3136a, -0x12b2d, -0x42a99, -0x572c4, -0x517d3, -0x396a4, -0x19c13, 0x34fc, 0x16e3b, 0x1e848, 0x1bc68, 0x12cbd
}
Similar output is produced. In addition to the filter coefficient array,
stage2.py outputs a right-shift (here 4) which is needed by the second
stage filter.
The simplest way to use these coefficients in an application is to replace the
values in ../lib_mic_array/src/etc/stage1_fir_coef.c and
../lib_mic_array/src/etc/stage2_fir_coef.c.
Input pkl File#
stage1.py and stage2.py load the contents of the supplied .pkl file
using pickle.load()` from the pickle Python module. They expect the
result of load() to have type compatible with
Tuple[Tuple[numpy.ndarray,int],Tuple[numpy.ndarray,int]]. The following
pseudo-code should help clarify this:
stage1, stage2 = pkl.load(filter_coef_pkl_file)
stage1_coef_array, stage1_decimation_factor = stage1
stage2_coef_array, stage2_decimation_factor = stage2
assert stage1_coef_array.dtype == np.int16
assert stage2_coef_array.dtype == np.int32
assert stage1_decimation_factor == 32
Further constraints, as illustrated above, are that the stage1 filter
coefficients should be np.int16 (signed 16-bit integers) and stage2 filter
coeffiients should be np.int32 (signed 32-bit integers). Further, the first
stage filter currently only supports a decimation factor of 32.
Using Custom Coefficients in an Application#
The C files ../lib_mic_array/src/etc/stage1_fir_coef.c and
../lib_mic_array/src/etc/stage2_fir_coef.c provide an example of how the outputs
of stage1.py and stage2.py may be used.
Note
If the stage 2 decimation factor or tap count changes ../lib_mic_array/api/etc/filters_default.h must also be updated to reflect that change.
The filter coefficients used by the decimator as specified when initializing the
decimator (e.g. mic_array::TwoStageDecimator). To use custom coefficients
when directly working with the mic array’s C++ objects, simply provide a pointer
to your custom coefficients to the decimator’s Init() method.
Alternatively, lib_mic_array’s Vanilla API and the
mic_array::prefab::BasicMicArray class template both automatically use the
filter coefficients given by the symbols stage1_coef, stage2_coef and
stage2_shr when initializing the decimator.
In that case, there are two options to use custom filter. The first and easiest
is to simply overwrite the coefficients given in
../lib_mic_array/src/etc/stage1_fir_coef.c and
../lib_mic_array/src/etc/stage2_fir_coef.c. If that is not an option, you
may also add your own source files containing your coefficients to your project
(using the same symbol names) and exclude stage1_fir_coef.c and
stage2_fircoef.c from the project’s source files.