4 Mic xCORE Array Microphone

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
JordenLuke
Member
Posts: 10
Joined: Fri Aug 11, 2017 6:21 pm
Contact:

Post by JordenLuke »

I have two questions about this application note I have been working with. From what I can tell the data is stored in the variable current of the type mic_array_frame time_domain struct. How can this data be accessed? How can it be sent out over TDM? I have set up a TDM peripheral in the xmos chip. I am just not understanding how put the 4 mic channels I have into the TDM allowing it be transmitted to another device for further processing. Any suggestions would be very helpful.


User avatar
andrew
Experienced Member
Posts: 114
Joined: Fri Dec 11, 2009 10:22 am

Post by andrew »

mic_array_frame_time_domain * current =
mic_array_get_next_time_domain_frame(c_ds_output, DECIMATOR_COUNT, buffer, audio, dc);
will get the latest frame of data from the mic_array when it's ready.

current->data[channel_number][sample_number]
will get from channel channel_number the sample sample_number where 0 is the oldest and 2^n is the latest.
JordenLuke
Member
Posts: 10
Joined: Fri Aug 11, 2017 6:21 pm
Contact:

Post by JordenLuke »

I have tried to send this data out using TDM. If fallowed the guide provided with the I2S library. I am not sure what the problem is. Is there a better guide to explain how to set up the TDM? Here is my code if you anyone could tell me what I am doing wrong.
// Copyright (c) 2015-2016, XMOS Ltd, All rights reserved
#include <platform.h>
#include <xs1.h>
#include <string.h>
#include <i2s.h>

#include "mic_array.h"

//setup of PDM Mics
on tile[0]: in port p_pdm_clk = XS1_PORT_1E;
on tile[0]: in buffered port:32 p_pdm_mics = XS1_PORT_8B;
on tile[0]: in port p_mclk = XS1_PORT_1F;
on tile[0]: clock pdmclk = XS1_CLKBLK_1;

//Setup of TMD master interface
on tile[0]: out buffered port:32 p_dout[1] = {XS1_PORT_1K}; // output to the TDM X0D34
on tile[0]: in port p_bclk = XS1_PORT_1L; //input bit clk X0D35
on tile[0]: out buffered port:32 p_fsync = XS1_PORT_1M; //XOD36
on tile[0]: clock bclk = XS1_CLKBLK_2;



#define DECIMATION_FACTOR 6 //Corresponds to a 16kHz output sample rate
#define DECIMATOR_COUNT 1 //8 channels requires 2 decimators
#define FRAME_BUFFER_COUNT 2 //The minimum of 2 will suffice for this example

#define DECIMATOR_CH_COUNT 4 //Just to be clear

int data[DECIMATOR_COUNT*DECIMATOR_CH_COUNT]
[THIRD_STAGE_COEFS_PER_STAGE*DECIMATION_FACTOR];

void example(streaming chanend c_ds_output[DECIMATOR_COUNT], server i2s_callback_if tdm_i) {
unsafe{
mic_array_frame_time_domain audio[FRAME_BUFFER_COUNT];

unsigned buffer; //No need to initialize this.
memset(data, 0, DECIMATOR_COUNT*DECIMATOR_CH_COUNT*
THIRD_STAGE_COEFS_PER_STAGE*DECIMATION_FACTOR*sizeof(int));

mic_array_decimator_conf_common_t dcc = {
0, // Frame size log 2 is set to 0, i.e. one sample per channel will be present in each frame
1, // DC offset elimination is turned on
0, // Index bit reversal is off
0, // No windowing function is being applied
DECIMATION_FACTOR,// The decimation factor is set to 6
g_third_stage_div_6_fir, // This corresponds to a 16kHz output hence this coef array is used
0, // Gain compensation is turned off
FIR_COMPENSATOR_DIV_6, // FIR compensation is set to the corresponding coefficients
DECIMATOR_NO_FRAME_OVERLAP, // Frame overlapping is turned off
FRAME_BUFFER_COUNT // The number of buffers in the audio array
};

mic_array_decimator_config_t dc[DECIMATOR_COUNT] = {
{
&dcc,
data[0], // The storage area for the output decimator
{INT_MAX, INT_MAX, INT_MAX, INT_MAX}, // Microphone gain compensation (turned off)
4 // Enabled channel count (currently must be 4)
},
/* {
&dcc,
data[4], // The storage area for the output decimator
{INT_MAX, INT_MAX, INT_MAX, INT_MAX}, // Microphone gain compensation (turned off)
4 // Enabled channel count (currently must be 4)
}*/
};
mic_array_decimator_configure(c_ds_output, DECIMATOR_COUNT, dc);

mic_array_init_time_domain_frame(c_ds_output, DECIMATOR_COUNT, buffer, audio, dc);

while(1){
mic_array_frame_time_domain * current =
mic_array_get_next_time_domain_frame(c_ds_output, DECIMATOR_COUNT, buffer, audio, dc);
select{
case tdm_i.init(i2s_config_t &?i2s_config, tdm_config_t &?tdm_config):
tdm_config.sync_len = 32;
tdm_config.channels_per_frame = 4;

break;
case tdm_i.restart_check()-> i2s_restart_t restart:
break;

case tdm_i.send(size_t index)-> int32_t sample:
sample = current->data[index][0]; //place microphone data in TDM slot
break;
case tdm_i.receive(size_t index, int32_t sample): //Don't expect to receive any
break;
}

}
}
}

int main(){
par{
on tile[0]:{
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);

//setting up the i2s tdm
interface i2s_callback_if tdm_i;
configure_clock_src(bclk,p_bclk);
// start_clock(bclk);

streaming chan c_pdm_to_dec[DECIMATOR_COUNT];
streaming chan c_ds_output[DECIMATOR_COUNT];

par{
mic_array_pdm_rx(p_pdm_mics, c_pdm_to_dec[0], null);
mic_array_decimate_to_pcm_4ch(c_pdm_to_dec[0], c_ds_output[0], MIC_ARRAY_NO_INTERNAL_CHANS);
//mic_array_decimate_to_pcm_4ch(c_pdm_to_dec[1], c_ds_output[1], MIC_ARRAY_NO_INTERNAL_CHANS);

//set up of the TDM clock
tdm_master(tdm_i,p_fsync,p_dout,1,null,0,bclk);
example(c_ds_output,tdm_i);

}
}
}
return 0;
}

I am also questioning if my tile clock is incorrect.
Post Reply