The Vanilla API is a small optional API which greatly simplifies the process of including a mic array unit in an xcore.ai application. Most applications that make use of a PDM mic array will not have complicated needs from the mic array software component beyond delivery of frames of audio data from a configurable set of microphones at a configurable rate. This API targets that majority of applications.
The prefab API requires the application developer to have at least some minimal understanding of the objects and classes associated with the mic array unit, and requires the developer to write some application-specific code to configure and start the mic array. The Vanilla API (which builds on top of the prefab model) by contrast, requires as little as two standard function calls, and instead moves the majority of the application logic into the application’s build project.
Why “Vanilla”? “Vanilla” was originally meant as a generic placeholder name, but no better name was ever suggested.
How It Works#
The Vanilla API comprises two code files,
etc/vanilla/mic_array_vanilla.h which are not compiled as part of this
library. Instead, if used, these are added to the application target’s build. To
control configuration, the source file relies on a set of pre-processor macros
(added via compile flags) which determine how the mic array unit will be
The API is included in an application by using a CMake macro
mic_array_vanilla_add()) provided in this library. The macro updates the
application’s sources, includes and compile definitions to include the API.
In the application code, two function calls are needed. First,
ma_vanilla_init() is called to initialize the various mic array
sub-components, preparing for capture of PDM data. Then, to start capture the
decimation thread is started with
ma_vanilla_task() as entrypoint.
ma_vanilla_task() takes an XCore
chanend as a parameter, which
tells it where completed audio frames should be routed.
The Vanilla API runs the PDM rx service as an interrupt in the decimation thread. To run it as a separate thread (for reduced total MIPS consumption) one of the lower-level APIs must be used.
The Vanilla API uses the default filters provided with this library, and does not currently provide a way to override this. To use custom filters, you must either use a lower-level API or modify the vanilla API.
Configuration with the Vanilla API is achieved through compile definitions. The
required definitions are provided through the
There are several additional optional definitions.
mic_array_vanilla_add() is the CMake macro used to add the Vanilla API to an
macro( mic_array_vanilla_add TARGET_NAME MCLK_FREQ PDM_FREQ MIC_COUNT SAMPLES_PER_FRAME )
The name of the application’s CMake target. It is the target the Vanilla API is added to.
The known frequency, in Hz, of the application’s master audio clock. A typical frequency is 24576000 Hz. Note that this parameter is not configuring the master audio clock. (Equivalent compile definition:
The desired frequency, in Hz, of the PDM clock. This should be an integer factor of
510. (Equivalent compile definition:
The number of PDM microphone channels to be captured. This API supports values of
8(SDR/DDR). This value must match the configuration (SDR/DDR) and port width of the PDM capture port. That is, in an SDR port configuration,
MIC_COUNTmust equal the capture port width, and in DDR port configuration,
MIC_COUNTmust be twice the port width. (Equivalent compile definition:
This API does not support capturing only a subset of the capture port’s channels, e.g. capturing only 3 channels on a 4-bit port. To accomplish this the prefab API should be used.
Though listed under Optional Configuration below, if the microphones are in
a DDR configuration and
MIC_COUNT is not
2, the application must
SAMPLES_PER_FRAME is the number of samples (for each microphone channel)
that will be delivered in each (non-overlapping) frame retrieved by
ma_frame_rx(). A minimum value of
1 is supported, to deliver
samples one at a time. The larger this value, the looser the real-time
constraint on the thread receiving the mic array unit’s output (while also
increasing the amount of audio data to be processed).
These are configuration parameters that receive default values but can be
optionally overridden by an application. These can be defined in your
CMakeLists.txt using CMake’s built-in
Indicates whether the microphones are arranged in an SDR (
0) or DDR (
1) configuration. An SDR configuration is one in which each port pin is connected to a single PDM microphone. A DDR configuration is one which each port pin is connected to two PDM microphoes. Defaults to
2in which case it defaults to
Indicates whether the DC offset elmination filter should be applied to the output of the decimator. Set to
0to disable or
1to enable. Defaults to
The next three parameters are the identifiers for hardware port resources used
by the mic array unit. They can be specified as either the identifier listed in
your device’s datasheet (e.g.
XS1_PORT_1D) or as an alias fort he port
listed in your application’s XN file (e.g.
PORT_MCLK_IN_OUT). For example:
... <Tile Number="0" Reference="tile"> ... <Port Location="XS1_PORT_1D" Name="PORT_MCLK_IN_OUT"/> ... </Tile> ...
Identifier of the 1-bit port on which the device is receiving the master audio clock. Defaults to
Identifier of the 1-bit port on which the device will signal the PDM clock to the microphones. Defaults to
Identifier of the port on which the device will capture PDM sample data. The port width of this port must match the
MIC_COUNTparameter given to
mic_array_vanilla_add()and the value of
MIC_ARRAY_CONFIG_USE_DDR. Defaults to
The final two parameters indicate which clock block resource(s) should be used
to generate the PDM clock and the capture clock. An xcore.ai device provides 5
hardware clock blocks for application use, identified as
XS1_CLKBLK_5. The device’s clock blocks are interchangeable, but if
another component of your application uses one of these defaults, you may need
to change these parameters.
Clock block used as ‘clock A’ (see Getting Started). This clock block is used in both SDR and DDR configurations.
Clock block used as ‘clock B’ (see Getting Started). This clock block is only needed in DDR configurations and is ignored (not configured) in SDR configurations.
Vanilla API with other Build Systems#
Using the Vanilla API with build systems other than CMake is simple.
Add the file
etc/vanilla/mic_array_vanilla.cppto the application’s source files.
etc/vanilla/(relative to repository root) to the application include paths.
Add the compile definitions for the parameters listed in the previous sections (each parameter beginning with
MIC_ARRAY_CONFIG_) to the compile options for