PdmRx.hpp¶
-
template<unsigned BLOCK_SIZE, class SubType>
class mic_array::PdmRxService¶ Used to collect PDM sample data from a port.
This class is used to collect blocks of PDM data from a port and send the data to a decimator for further processing.
PdmRxService
is a base class using CRTP. Subclasses extendPdmRxService
providing themselves as the template parameterSubType
.This base class provides the logic for aggregating PDM data taken from a port into blocks, and a subclass is required to provide methods
SubType::ReadPort()
andSubType::SendBlock()
.SubType::ReadPort()
is responsible for reading 1 word of data fromp_pdm_mics
.SubType::SendBlock()
is provided a block of PDM data as a pointer and is responsible for signaling that to the subsequent processing stage. (Called from PdmRx thread or ISR)SubType::GetPdmBlock()
(called from MicArray thread) is responsible for receiving a block of PDM data fromSubType::SendBlock()
as a pointer, deinterleaving the buffer contents, and returning a pointer to the PDM data in the format expected by the mic array unit’s decimator component.- Template Parameters
BLOCK_SIZE – Number of words of PDM data per block.
SubType – Subclass of
PdmRxService
Public Functions
-
void SetPort(port_t p_pdm_mics)¶
Set the port from which to collect PDM samples.
-
void ProcessNext()¶
Perform a port read and if a new block has completed, signal.
-
void ThreadEntry()¶
Entry point for PDM processing thread.
This function loops forever, calling
ProcessNext()
with each iteration.
Public Static Attributes
-
static constexpr unsigned BlockSize = BLOCK_SIZE¶
Number of words of PDM data per block.
-
template<unsigned CHANNELS_IN, unsigned CHANNELS_OUT, unsigned SUBBLOCKS>
class mic_array::StandardPdmRxService : public mic_array::PdmRxService<CHANNELS_IN * SUBBLOCKS, StandardPdmRxService<CHANNELS_IN, CHANNELS_OUT, SUBBLOCKS>>¶ PDM rx service which uses a streaming channel to send a block of data by pointer.
This class can run the PDM rx service either as a stand-alone thread or through an interrupt.
A streaming channel is used to transfer control of the PDM data block between contexts (i.e. thread->thread or ISR->thread).
- Inter-context Transfer
The
MicArray
unit receives blocks of PDM data from an instance of this class by callingGetPdmBlock()
, which blocks until a new PDM block is available.The buffer transferred by
SendBlock()
containsCHANNELS_IN*
SUBBLOCKSwords of PDM data for
CHANNELS_INmicrophone channels. The words are stored in reverse order of arrival. See
deinterleave_pdm_samples<>()` for additional details on this format.- Layouts
Within
GetPdmBlock()
(i.e. mic array thread) the PDM data block is deinterleaved and copied to another buffer in the format required by the decimator component, which is returned byGetPdmBlock()
. This buffer contains samples forCHANNELS_OUT
microphone channels.In some cases an application may be required to capture more microphone channels than should actually be processed by subsequent processing stages (including the decimator component). For example, this may be the case if 4 microphone channels are desired but only an 8 bit wide port is physically available to capture the samples.
- Channel Filtering
This class template has a parameter both for the number of channels to be captured by the port (
CHANNELS_IN
), as well as for the number of channels that are to be output for consumption by theMicArray
’s decimator component (CHANNELS_OUT
).When the PDM microphones are in an SDR configuration,
CHANNELS_IN
must be the width (in bits) of the xCore port to which the microphones are physically connected. When in a DDR configuration,CHANNELS_IN
must be twice the width (in bits) of the xCore port to which the microphones are physically connected.CHANNELS_OUT
is the number of microphone channels to be consumed by the decimator unit (i.e. must be the same as theMIC_COUNT
template parameter of the decimator component). If all port pins are connected to microphones, this parameter will generally be the same asCHANNELS_IN
.The input channel index of a microphone depends on the pin to which it is connected. Each pin connected to a port has a bit index for that port, given in the ‘Signal Description and GPIO’ section of your package’s datasheet.
- Channel Index (Re-)Mapping
Suppose an
N
-bit port is used to capture microphone data, and a microphone is connected to bitB
of that port. In an SDR microphone configuration, the input channel index of that microphone isB
— the same as the port bit index.In a DDR configuration, that microphone will be on either input channel index
B
orB+N
, depending on whether that microphone is configured for in-phase capture or out-of-phase capture.Sometimes it may be desirable to re-order the microphone channel indices. This is likely the case, for example, when
CHANNELS_IN > CHANNELS_OUT
.By default output channels are mapped from the input channels with the same index. If
CHANNELS_IN > CHANNELS_OUT
, this means that the input channels with the highestCHANNELS_IN-CHANNELS_OUT
indices are dropped by default.The
MapChannel()
andMapChannels()
methods can be used to specify a non-default mapping from input channel indices to output channel indices. It takes a pointer to aCHANNELS_OUT
-element array specifying the input channel index for each output channel.- Template Parameters
CHANNELS_IN – The number of microphone channels to be captured by the port.
CHANNELS_OUT – The number of microphone channels to be delivered by this
StandardPdmRxService
instance.SUBBLOCKS – The number of 32-sample sub-blocks to be captured for each microphone channel.
Public Functions
-
uint32_t ReadPort()¶
Read a word of PDM data from the port.
- Returns
A
uint32_t
containing 32 PDM samples. IfMIC_COUNT >= 2
the samples from each port will be interleaved together.
-
void SendBlock(uint32_t block[CHANNELS_IN * SUBBLOCKS])¶
Send a block of PDM data to a listener.
- Parameters
block – PDM data to send.
-
void Init(port_t p_pdm_mics)¶
Initialize this object with a channel and port.
- Parameters
p_pdm_mics – Port to receive PDM data on.
-
void MapChannels(unsigned map[CHANNELS_OUT])¶
Set the input-output mapping for all output channels.
By default, input channel index
k
maps to output channel indexk
.This method overrides that behavior for all channels, re-mapping each output channel such that output channel
k
is derived from input channelmap[k]
.Note
Changing the channel mapping while the mic array unit is running is not recommended.
- Parameters
map – Array containing new channel map.
-
void MapChannel(unsigned out_channel, unsigned in_channel)¶
Set the input-output mapping for a single output channel.
By default, input channel index
k
maps to output channel indexk
.This method overrides that behavior for a single output channel, configuring output channel
out_channel
to be derived from input channelin_channel
.Note
Changing the channel mapping while the mic array unit is running is not recommended.
- Parameters
out_channel – Output channel index to be re-mapped.
in_channel – New source channel index for
out_channel
.
-
void InstallISR()¶
Install ISR for PDM reception on the current core.
Note
This does not unmask interrupts.
-
void UnmaskISR()¶
Unmask interrupts on the current core.
-
uint32_t *GetPdmBlock()¶
Get a block of PDM data.
Because blocks of PDM samples are delivered by pointer, the caller must either copy the samples or finish processing them before the next block of samples is ready, or the data will be clobbered.
Note
This is a blocking call.
- Returns
Pointer to block of PDM data.