头像
tonylabs
主题 作者
帖子: 131
注册: 26 3月 2016, 20:27

【XMOS Library】Microphone Array 3.0.0

22 2月 2017, 09:22

Microphone Array Library 是用于 PDM 数字麦克风的接口

技术特性
麦克风阵列支援库支持一下特性:
  • 48kHz, 24kHz, 16kHz, 12kHz and 8kHz 输出采样率 (3.072MHz PDM clock)
  • 44.1kHz, 22.05kHz, 14.7kHz, 11.025kHz and 7.35kHz 输出采样率 (2.8224MHz PDM clock)
  • 可支持 4, 8, 12 或 16 个数字麦克风接口
  • 所有输出采样频率的阻带衰减不小于 80dB
  • 可配置的延迟,纹波和带宽
  • 成帧,可配置帧大小从 1 个到 8192 个样本加上50%重叠帧
  • 窗口和采样索引位在帧内反转
  • 独立麦克风增益补偿
  • DC 偏移消除
  • 最高达 3.072MHz 输入采样率
  • 高分辨率麦克风专用线路,仅 2.63 微秒延迟
  • 单任务进程仅需要 62.5 MIPS (单字长定点指令平均执行速度)来运行
组件
  • 数字麦克风 PDM 接口
  • 四通道抽取器
  • 高分辨率延迟区块
Software version and dependencies
This document pertains to version 3.0.0 of this library. It is known to work on version 14.2.4 of the
xTIMEcomposer tools suite, it may work
下面我们了解一下本库支持的几种典型设计。Microphone Array 库支持最多高达 16 个数字麦克风接口 mic_array_pdm_rx(),1 - 4 个处理任务,每个进程最多支援 4 通道 mic_array_decimate_to_pcm_4ch(),需要最多两个逻 on other versions.

库依赖:
  • lib_xassert (>=3.0.0)
  • lib_dsp (>=3.0.0)
1 总览辑核心

3. 硬件特性
数字麦克风 ( PDM ) 需要一个输入端时钟(需要一个时钟源外部电路),并在输出端提供数字麦克风信号,所有的 PDM 共享同一个时钟信号,输出 8 路数据至一个单 8 位端口。
  • 时钟, the PDM clock the used by the microphones to drive the data out.
The data from the PDM microphones on an 8 bit port.


The only port passed into the library is the 8-bit data port. The library assumes that the input port is
clocked using the PDM clock and requires no knowledge of PDM clock source. If a clock block pdmclk is
clocked at a 3.072 MHz rate, and the 8-bit port is p_pdm_mics then the following statements will ensure
that the PDM data port is clocked by the PDM clock:
代码: 全选
configure_in_port(p_pdm_mics, pdmclk);
start_clock(pdmclk);
The input clock for the microphones can be generated in a multitude of ways. For example, a 3.072MHz
clock can be generated on the board, or the xCORE can divide down 12.288 MHz master clock. Or, if clock
accuracy is not important, the internal 100 MHz reference can be divided down to provide an approximate
clock.
If an external master clock is input to the xCORE on a 1-bit port p_mclk that is running at 4x the desired
PDM clock, then the PDM clock can be generated by using the divider in a clock block:
代码: 全选
configure_clock_src_divide(pdmclk, p_mclk, 4);
configure_port_clock_output(p_pdm_clk, pdmclk);
configure_in_port(p_pdm_mics, pdmclk);
start_clock(pdmclk);

An approximate clock can be generated from the 500 MHz xCORE clock as follows:

代码: 全选
configure_clock_xcore(pdmclk, 82);
configure_port_clock_output(p_pdm_clk, pdmclk);
configure_in_port(p_pdm_mics, pdmclk);
start_clock(pdmclk);
It should be noted that this is a 3.048 MHz clock, which is 0.75% off a true 3.072 MHz clock. Finally, an
approximate clock can also be generated from the 100 MHz reference clock as follows:
代码: 全选
configure_clock_ref(pdmclk, 17);
configure_port_clock_output(p_pdm_clk, pdmclk);
configure_in_port(p_pdm_mics, pdmclk);
start_clock(pdmclk);
This gives a 2.941 MHz clock, which is 4.25% off a true 3.072 MHz clock. This may be acceptable to
simple Voice User Interfaces (VUIs).


3.1 PDM Microphones

PDM microphones typically have an initialization delay in the order of about 28ms. They also typically
have a DC offset. Both of these will be specified in the datasheet.

All PDM microphone functions are accessed via the mic_array.h header:

代码: 全选
#include <mic_array.h>
You also have to add lib_mic_array to the USED_MODULES field of your application Makefile.
A project must also include an extra header mic_array_conf.h which is used to describe the mandatory
configuration described later in this document.
The PDM microphone interface and 4-channel decimators are instantiated as parallel tasks that run in a
par statement. For example, in an eight channel setup the two 4-channel decimators must connect to the
PDM interface via streaming channels:

代码: 全选
#include <mic_array.h>
clock pdmclk;
in buffered port:32 p_pdm_mics = XS1_PORT_8B;
in port p_mclk = XS1_PORT_1E;
out port p_pdm_clk = XS1_PORT_1F;
int main() {
streaming chan c_pdm_to_dec[2];
streaming chan c_ds_output[2];
configure_clock_src_divide(pdmclk, p_mclk, 4);
configure_port_clock_output(p_pdm_clk, pdmclk);
configure_in_port(p_pdm_mics, pdmclk);
start_clock(pdmclk);
par {
mic_array_pdm_rx(p_pdm_mics, c_pdm_to_dec[0], c_pdm_to_dec[1]);
mic_array_decimate_to_pcm_4ch(c_pdm_to_dec[0], c_ds_output[0]);
mic_array_decimate_to_pcm_4ch(c_pdm_to_dec[1], c_ds_output[1]);
application(c_ds_output);
}
return 0;
}
There is a further requirement that any application of a mic_array_decimate_to_pcm_4ch() task must
be on the same tile as the mic_array_decimate_to_pcm_4ch() task due to the sharaed frame memory.
As the PDM interface mic_array_pdm_rx() communicates over channels then the placement of it is not
restricted to the same tile as the decimators.
Additionally, the high resolution delay task can be inserted between the PDM interface and the decimators
in the following fashion:

代码: 全选
#include <mic_array.h>
clock pdmclk;
in buffered port:32 p_pdm_mics = XS1_PORT_8B;
in port p_mclk = XS1_PORT_1E;
out port p_pdm_clk = XS1_PORT_1F;
int main() {
streaming chan c_pdm_to_hires[2];
streaming chan c_hires_to_dec[2];
streaming chan c_ds_output[2];
chan c_cmd;
configure_clock_src_divide(pdmclk, p_mclk, 4);
configure_port_clock_output(p_pdm_clk, pdmclk);
configure_in_port(p_pdm_mics, pdmclk);
start_clock(pdmclk);
par {
mic_array_pdm_rx(p_pdm_mics, c_pdm_to_hires[0], c_pdm_to_hires[1]);
mic_array_hires_delay(c_pdm_to_hires, c_hires_to_dec, 2, c_cmd);
mic_array_decimate_to_pcm_4ch(c_hires_to_dec[0], c_ds_output[0]);
mic_array_decimate_to_pcm_4ch(c_hires_to_dec[1], c_ds_output[1]);
application(c_ds_output, c_cmd);
}
return 0;
}
Note, using the high resolution delay consumes an extra logical core.

5 High resolution delay task
想做就去做