Scripts

stage1.py, stage2.py and combined.py

These scripts can be used to generate C code representing the required first and second stage filters used by the mic array.

  • stage1.py outputs first stage filter coefficients array and parameter defines

  • stage2.py outputs second stage filter coefficients array and parameter defines

  • combined.py outputs both first and second stage filter coefficients array and parameter defines

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. The scripts take optional parameters --file-prefix and --file-dir that can optionally generate a <prefix>.h header file with the filter array and #defines. Run python <stage1/stage2/combined>.py --help for more information.

Example

The following is an example of running stage1.py from the repo root.

cd 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



#define CUSTOM_FILT_STG1_DECIMATION_FACTOR   32
#define CUSTOM_FILT_STG1_TAP_COUNT           256
#define CUSTOM_FILT_STG1_SHR                 0 /*shr not relevant for stage 1*/


uint32_t custom_filt_stg1_coef[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 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. From the repo root, run:

cd 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



#define CUSTOM_FILT_STG2_DECIMATION_FACTOR   6
#define CUSTOM_FILT_STG2_TAP_COUNT           256
#define CUSTOM_FILT_STG2_SHR                 1


int32_t custom_filt_stg2_coef[256] = {
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.

The simplest way to use these coefficients in an application is to run this from the repo root:

cd python
python combined.py filter_design/good_2_stage_filter_int.pkl --file-prefix custom_filter

and include the generated custom_filter.h file in the application.

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 application should use the mic array custom filter API (mic_array_init_custom_filter) when including a custom filter that is not part of the default filter provided by the library. Refer to app_custom_filter for an example of using the custom filter API.